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

哪种方式最适合Python工厂注册?,python,python-3.x,python-decorators,idioms,Python,Python 3.x,Python Decorators,Idioms,这是一个关于这些方法中哪一种被认为是最具python风格的问题。我不是在寻找个人意见,而是什么是惯用语。我的背景不是Python,因此这将对我有所帮助 我正在从事一个可扩展的Python3项目。这个想法与工厂模式类似,只是它基于功能 本质上,用户将能够创建一个自定义函数(跨包和项目),我的工具可以定位并动态调用该函数。它还可以使用currying传递参数(但此处不包括该代码) 我的目标是遵循良好的蟒蛇练习。我在两种策略之间左右为难。而且,由于Python不是我的专长,我想知道以下做法的优缺点:

这是一个关于这些方法中哪一种被认为是最具python风格的问题。我不是在寻找个人意见,而是什么是惯用语。我的背景不是Python,因此这将对我有所帮助

我正在从事一个可扩展的Python3项目。这个想法与工厂模式类似,只是它基于功能

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

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

  • 使用装饰师

    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')
    
    这似乎是合理的,但对于那些不熟悉装饰师的人来说确实有点不可思议

  • 强制对抽象类进行子分类,并使用
    \uuu子类\uuuu()

    如果使用子类,则无需注册。然而,我觉得这迫使我们在不需要完整类的情况下定义类。此外,在引擎盖下使用
    。\uuuu子类\uuuuu()
    ,对消费者来说也似乎很神奇。然而,甚至Java也可以用来搜索带有注释的类

  • 明确注册

    忘记以上所有内容,强制进行显式注册。没有装修工。没有子类。就像这样:

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

  • 这个问题没有答案


    由Python基金会推动的唯一标准做法是: PEP 8很少涉及像这样的更高层次的“设计模式”问题,特别是与您的特定问题无关

    而且,即使它做到了,PEP8也只是一个明确的指导方针,Guido拒绝了将其作为某种广泛标准的建议,这种标准应该在每个Python项目上强制执行

    此外,它还强调了这一点


    当然,选择一种设计胜过另一种设计是有主观原因的

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


    也许有一些论点很吸引人,但这本身就是蒂姆·彼得斯试图将圭多自己的主观指导提炼成一系列精练的片段,而不是一个客观的来源。(任何一个简单的查看,例如,<代码> Python思想< /代码>列表,可以看到几乎任何问题的双方都可以求助于禅宗……

    Python基金会提出的唯一标准实践是PEP 8。PEP8只是“在主要Python发行版中包含标准库的代码”的指南。它强调了这只是一个指导方针,而不是一个严格的建议。但是,更重要的是,它与像这样的更高层次的“设计模式”问题几乎没有关系,与您的具体问题也没有关系。因此,唯一的答案是,就PSF的“推广标准实践”而言,您所做的并不重要。唯一的决定方法是基于主观的意见,这些意见可能会受到大型Python社区所认为的惯用语的指导,但这不会包含在任何您可以引用的客观文档中。我明白了,@abarnert。非常感谢。这是有道理的。我有一部分人希望在PEP 8之外有一个建议,但我想这种灵活性也允许社区进行清理并制定首选做法像这样的决策很难让人接受,我希望避免这种情况。如果你想要一些主观的评论:核心开发人员编写的代码,甚至是stdlib,都会做这两件事(以及其他选择,比如需要特定的基类或元类)。例如,
    isinstance(iter([1]),collections.abc.Iterable)
    之所以成立,是因为
    collections.abc
    调用
    Iterator.register(bytes\u Iterator)
    (词汇表甚至解释了这种“虚拟子类化”,因此它不仅仅是隐藏在幕后的一些实现细节)但是,如果你不使用decorator的主要原因是它们“对那些不熟悉decorator的人来说似乎有点神奇”,我认为这不是一个很好的理由,除非你的代码主要是由级别较低的新手或只会少量使用Python的人阅读。装饰器是该语言的一个重要特性,任何使用装饰器的项目的工作人员都会很快学会装饰器。