【发布时间】:2010-02-03 11:28:40
【问题描述】:
我想在基类中保留一个(所有,非立即包含的)子类的字典,以便我可以从字符串中实例化它们。我这样做是因为CLSID 是通过网络表单发送的,所以我想将选择限制为从子类中设置的选项。 (我不想eval()/globals() 类名)。
class BaseClass(object):
CLSID = 'base'
CLASSES = {}
def from_string(str):
return CLASSES[str]()
class Foo(BaseClass):
CLSID = 'foo'
BaseClass.CLASSES[CLSID] = Foo
class Bar(BaseClass):
CLSID = 'bar'
BaseClass.CLASSES[CLSID] = Bar
这显然行不通。但是有没有像@classmethod 这样的初始化?这个想法是这个类方法只会在每个类被读取并将类注册到基类时运行一次。像下面这样的东西可以工作:(也可以在Foo和Bar中保存额外的行)
class BaseClass(object):
CLSID = 'base'
CLASSES = {}
@classmethod
def __init__(cls):
BaseClass.CLASSES[cls.CLSID] = cls
def from_string(str):
return CLASSES[str]()
我曾考虑在CLSID 上使用__subclasses__,然后使用filter(),但这仅适用于直接子类。
所以,希望我解释我的目的,问题是如何使这项工作?还是我的做法完全错误?
【问题讨论】:
-
通常我们为此使用单独的工厂,而不是超类。为什么不使用更常见的 Factory 设计模式?
-
我认为将工厂方法放在超类中会更干净。此外,我不想对类/ID 的选项进行硬编码,我希望任何子类也是自包含的,这样基类和工厂方法就可以保持为黑匣子。
-
将工厂放在超类中远非干净 - 正如您的问题所揭示的那样。 “硬编码选项?”没有意义。工厂就像超类一样是“黑匣子”,所以我不明白这一点。
-
我现在开始看到了 :)。我想在这里进行硬编码:en.wikipedia.org/wiki/Factory_method_pattern#ActionScript_3.0,
PizzaFactory类。
标签: python inheritance class