哪种方式最适合Python工厂注册?

cod*_*ded 5 python idioms python-3.x python-decorators

这是一个关于这些方法中的哪一个被认为是最Pythonic 的问题。我不是在寻找个人意见,而是在寻找什么是惯用的。我的背景不是 Python,所以这对我有帮助。

我正在开发一个可扩展的 Python 3 项目。这个想法类似于工厂模式,只是它基于函数。

本质上,用户将能够创建一个自定义函数(跨包和项目),我的工具可以找到并动态调用该函数。它还可以使用柯里化来向下传递参数(但此处不包含该代码)

我的目标是遵循良好的 Pythonic 实践。我在两种策略之间左右为难。而且,由于 Python 不是我的专长,我想知道以下做法的优缺点:

  1. 使用装饰器

    registered = {}
    
    def factoried(name):
        def __inner_factory_function(fn):
            registered[name] = fn
            return fn
        return __inner_factory_function
    
    
    def get_function(name):
        return registered[name]
    
    Run Code Online (Sandbox Code Playgroud)

    然后,下面的函数就自动注册了...

    @factoried('foo')
    def build_foo():
      print('hi')
    
    Run Code Online (Sandbox Code Playgroud)

    这看起来很合理,但对于那些不熟悉装饰器的人来说确实有点神奇。

  2. 强制对抽象类进行子类化并使用 __subclasses__()

    如果使用子类,则无需注册。但是,我觉得这会在可能不需要完整类时强制定义类。此外,.__subclasses__()引擎盖下的使用对消费者来说也很神奇。但是,即使是 Java 也可以用于搜索带有注释的类。

  3. 显式注册

    忘记以上所有内容并强制显式注册。没有装饰器。没有子类。就像这样:

    def build_foo():
      # ...
    
    factory.register('foo', build_foo)
    
    Run Code Online (Sandbox Code Playgroud)

aba*_*ert 2

这个问题没有答案。

\n\n

Python 基金会提倡的唯一标准实践是PEP 8

\n\n

PEP 8 与此类更高级别的“设计模式”问题几乎没有关系,特别是与您的具体问题没有任何关系。

\n\n

而且,即使确实如此,PEP 8 也明确只是“包含主要 Python 发行版中的标准库的代码”的指南,而 Guido 拒绝了使其成为某种应该在每个 Python 上强制执行的广泛标准的建议。项目。

\n\n

另外,它强调了这一点:这只是一个指导方针,而不是一个严格的建议

\n\n
\n\n

当然,人们更喜欢一种设计而不是另一种设计是有主观原因的。

\n\n

理想情况下,这些主观原因通常是由一些社区对“惯用”或“Pythonic”的共识所驱动的。但社区共识并没有作为您可以引用的客观来源记录在任何地方。

\n\n

可能有一些论点吸引了《Python 之禅》,但这本身只是 Tim Peters 试图将 Guido 自己的主观指南提炼成一系列精辟的原话集,而不是客观来源。(任何简单浏览一下该python-ideas列表的人都可以看到,几乎任何问题的双方都可以诉诸 Zen\xe2\x80\xa6)

\n