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



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

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

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

我的目标是遵循良好的 Python 实践。我在两种策略之间左右为难。而且,由于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]
    

    然后,以下函数会自动注册...

    @factoried('foo')
    def build_foo():
    print('hi')
    

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

  2. 强制抽象类的子类化和使用__subclasses__()

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

  3. 显式注册

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

    def build_foo():
    # ...
    factory.register('foo', build_foo)
    

这个问题没有答案。

Python 基金会推广的唯一标准实践是 PEP 8。

PEP 8 与像这样的更高级别的"设计模式"问题几乎没有关系,特别是与您的特定问题无关。

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

此外,它强调它只是一个指导方针,而不是一个严格的建议。


当然,有主观原因偏爱一种设计而不是另一种设计。

理想情况下,这些主观原因通常是由一些社区对"惯用语"或"pythonic"的共识驱动的。但是,社区共识并没有写在任何地方,作为你可以引用的客观来源。

可能有一些论点吸引着《蟒蛇的禅》,但这本身只是蒂姆·彼得斯(Tim Peters(试图将圭多自己的主观准则提炼成一系列精辟的声音片段,而不是客观来源。(任何简要看一下python-ideas列表的人都可以看到,几乎任何问题的双方都可以诉诸禅宗......

最新更新