我有一些单个父类的子类,并希望根据序列化数据中的字符串实例化它们。我的方法是将实例化字符串映射到类,然后使用工厂方法创建相应的对象:
class Superclass:
@classmethod
def get_instance(cls, string):
return CLASSMAP[string]()
def name(self):
pass
class Foo(Superclass):
def name(self):
return "my name is Foo"
class Bar(Superclass):
def name(self):
return "i'm Bar"
class Baz(Superclass):
def name(self):
return "i am called Baz"
CLASSMAP = {
'foo': Foo,
'bar': Bar,
'baz': Baz,
}
我不喜欢将CLASSMAP作为全局字典,但由于尚未定义子类,我无法在声明中将其定义为Superclass的成员(并且它们必须在超级,当然)。我当然可以在之后将类映射分配到类中:
Superclass.CLASSMAP = {...}
并拥有Superclass' get_instance()方法引用了尚未存在的字段,但它看起来更笨拙并容易出错。
整个模式是否有更多的Pythonic方法?
答案 0 :(得分:1)
如果你使超类成为继承自object的新式类,你可以使用cls.__subclasses__()
动态地解决这个问题:
class Superclass(object):
@classmethod
def get_instance(cls, string):
return next(c for c in cls.__subclasses__() if c.__name__.lower() == string)()
一种混合方法,结合了动态添加类的优势,同时仍然具有O(1)
类查找:
class Superclass(object):
@classmethod
def get_instance(cls, string):
return MAPPING[string]()
class Foo(Superclass):
lookup = 'foo'
class Bar(Superclass):
lookup = 'bar'
MAPPING = {c.lookup: c for c in Superclass.__subclasses__()}