哪种方式最适合Python工厂注册?
Which way is ideal for Python factory registration?
这是一个关于哪些方法被认为是最 Pythonic 的问题。我不是在寻找个人意见,而是在寻找什么是惯用的。我的背景不在Python,所以这对我有帮助。
我正在开发一个可扩展的 Python 3 项目。思路类似于工厂模式,只不过它是基于函数的。
基本上,用户将能够创建一个自定义函数(跨包和项目),我的工具可以定位并动态调用该函数。它还可以使用柯里化来向下传递参数(但此处不包含该代码)
我的目标是遵循良好的 Pythonic 做法。我在两种策略之间左右为难。而且,由于 Python 不是我的专长,我想知道以下做法的 pros/cons:
使用装饰器
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')
这似乎很合理,但对于那些不熟悉装饰器的人来说确实有点神奇。
强制子class摘要class并使用__subclasses__()
如果使用subclasses,则无需注册。但是,我觉得当可能不需要完整的 class 时,这会强制定义 classes。此外,在幕后使用 .__subclasses__()
对消费者来说也很神奇。但是,即使 Java 也可以用于搜索带注释的 classes。
显式注册
忘记以上所有内容并强制显式注册。没有装饰器。没有子classes。就像这样:
def build_foo():
# ...
factory.register('foo', build_foo)
这个问题没有答案。
Python 基金会提倡的唯一标准做法是 PEP 8。
PEP 8 与像这样的更高级别 "design-pattern" 问题几乎没有关系,尤其是与您的具体问题没有任何关系。
而且,即使是这样,PEP 8 明确只是 "code comprising the standard library in the main Python distribution" 的指南,Guido 拒绝了将其作为某种范围广泛的标准并应在每个 [=37] 上强制执行的建议=] 项目.
另外,它强调了 it's only a guideline, not a rigid recommendation.
当然,偏爱一种设计是有主观原因的。
理想情况下,这些主观原因通常是由社区对什么是 "idiomatic" 或 "pythonic" 的共识所驱动。但是社区共识并没有在任何地方记录下来,因为您可以引用一些 objective 来源。
可能存在吸引 The Zen of Python 的论点,但这本身只是 Tim Peters 试图将 Guido 自己的主观指南提炼成一系列精辟的声音片段,而不是 objective 来源。 (任何人只要稍微看一下 python-ideas
列表,就会发现几乎任何问题的两面都可以诉诸禅宗……)
这是一个关于哪些方法被认为是最 Pythonic 的问题。我不是在寻找个人意见,而是在寻找什么是惯用的。我的背景不在Python,所以这对我有帮助。
我正在开发一个可扩展的 Python 3 项目。思路类似于工厂模式,只不过它是基于函数的。
基本上,用户将能够创建一个自定义函数(跨包和项目),我的工具可以定位并动态调用该函数。它还可以使用柯里化来向下传递参数(但此处不包含该代码)
我的目标是遵循良好的 Pythonic 做法。我在两种策略之间左右为难。而且,由于 Python 不是我的专长,我想知道以下做法的 pros/cons:
使用装饰器
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')
这似乎很合理,但对于那些不熟悉装饰器的人来说确实有点神奇。
强制子class摘要class并使用
__subclasses__()
如果使用subclasses,则无需注册。但是,我觉得当可能不需要完整的 class 时,这会强制定义 classes。此外,在幕后使用
.__subclasses__()
对消费者来说也很神奇。但是,即使 Java 也可以用于搜索带注释的 classes。显式注册
忘记以上所有内容并强制显式注册。没有装饰器。没有子classes。就像这样:
def build_foo(): # ... factory.register('foo', build_foo)
这个问题没有答案。
Python 基金会提倡的唯一标准做法是 PEP 8。
PEP 8 与像这样的更高级别 "design-pattern" 问题几乎没有关系,尤其是与您的具体问题没有任何关系。
而且,即使是这样,PEP 8 明确只是 "code comprising the standard library in the main Python distribution" 的指南,Guido 拒绝了将其作为某种范围广泛的标准并应在每个 [=37] 上强制执行的建议=] 项目.
另外,它强调了 it's only a guideline, not a rigid recommendation.
当然,偏爱一种设计是有主观原因的。
理想情况下,这些主观原因通常是由社区对什么是 "idiomatic" 或 "pythonic" 的共识所驱动。但是社区共识并没有在任何地方记录下来,因为您可以引用一些 objective 来源。
可能存在吸引 The Zen of Python 的论点,但这本身只是 Tim Peters 试图将 Guido 自己的主观指南提炼成一系列精辟的声音片段,而不是 objective 来源。 (任何人只要稍微看一下 python-ideas
列表,就会发现几乎任何问题的两面都可以诉诸禅宗……)