vol*_*and 5 python factory class
我有一个父类的多个子类,并且想要根据序列化数据中的字符串实例化它们。我的方法是将实例化字符串映射到类,然后使用工厂方法创建相应的对象:
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,
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢将 CLASSMAP 作为全局字典,但我无法在声明中将其定义为超类的成员,因为子类尚未定义(当然,它们必须在超类之后定义) 。我当然可以随后将类映射分配给类:
Superclass.CLASSMAP = {...}
Run Code Online (Sandbox Code Playgroud)
并让超类的 get_instance() 方法引用尚不存在的字段,但它似乎更笨重并且容易出错。
整个模式是否有更 Pythonic 的方法?
如果您将超类设为继承自 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)()
Run Code Online (Sandbox Code Playgroud)
一种混合方法,结合了动态添加类的优点,同时仍然具有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__()}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2955 次 |
| 最近记录: |