我已阅读this SO discussion有关工厂方法的信息,并拥有alternate constructor用例。
我的班级看起来像这样:
class Foo(object):
def __init__(self, bar):
self.bar = bar
@classmethod
def from_data(cls, datafile):
bar = datafile.read_bar()
# Now I want to process bar in some way
bar = _process_bar(bar)
return cls(bar)
def _process_bar(self, bar)
return bar + 1
我的问题是,如果@classmethod
工厂方法想要在其代码中使用函数,那么该函数(_proces_bar
)应该是:
@classmethod
,这似乎有点奇怪,因为你不会像Foo._process_bar()
Foo
之外但在同一.py
文件中的方法。我跟这个一起去,但这看起来很奇怪。这些方法是否始终可用于Foo
的实例,而不管它是如何实例化的? (例如,如果它被保存到Pickle然后重新加载怎么办?假设课外的方法将无法使用!)@staticmethod
? (参见1.这看起来很奇怪) 答案 0 :(得分:1)
"正确的解决方案"取决于你的需求...
如果函数(_process_bar
)需要访问类Foo
(或者......的当前子类),那么你需要一个classmethod
- 应该是称为cls._process_bar()
,而不是Foo._process_bar()
。
如果函数不需要访问类本身但你仍然希望能够在子类中覆盖它(IOW:你想要基于类的多态),你需要一个{{1 }}
否则你只想要一个简单的功能。此功能代码存在的地方无关紧要,导入问题也是正交的。
此外,您可能(或不是,取决于您的具体用例)希望使用回调函数(可能具有默认值)允许更多灵活性,即:
staticmethod