我有以下代码:
class EntityBase (object) :
__entity__ = None
def __init__ (self) :
pass
def entity (name) :
class Entity (EntityBase) :
__entity__ = name
def __init__ (self) :
pass
return Entity
class Smth (entity ("SMTH")) :
def __init__ (self, a, b) :
self.a = a
self.b = b
# added after few comments -->
def factory (tag) :
for entity in EntityBase.__subclasses__ () :
if entity.__entity__ == tag :
return entity.__subclasses__ ()[0]
raise FactoryError (tag, "Unknown entity")
s = factory ("SMTH") (1, 2)
print (s.a, s.b)
# <--
现在在工厂里我可以得到EntityBase的所有子类,找到“SMTH”的具体子类并创建它。在
这是有效的方法还是我被误解和做错了什么?在
我会找个装修工来做。另外,在字典中存储entity->;子类映射可以让您用dict查找替换线性扫描。在
我不确定
__entity__
属性是否真的对您有用,或者您只是使用它来实现线性扫描。我保留了它,但是如果你去掉它,那么与实体相关的类甚至不需要从EntityBase
继承,你可以将它重命名为Registry
。这会使继承树变浅,并打开了在通过公共继承没有关联的类上使用的可能性。在根据您的用例是什么,更好的方法可能是
^{pr2}$让我们觉得字典是有用的,但我们自己觉得这本字典是好的,更花哨。这很容易理解,很难出错。除非你真的需要做些魔术,否则我认为那是正确的方法。你为什么要这么做?在
我想这是您想要Python metaclass的少数几种情况之一:
与代码的一些细微差别:
entity()
工厂函数创建一个子类,然后将该子类子类化。这种方法不仅创建了比所需的更多的子类,而且还会使代码无法工作,因为EntityBase.__subclasses__()
不包含Smth
类。在__
开头和结尾的标识符是为Python保留的,因此我使用_entity_
属性而不是{元类可以跟踪定义的类。
Register.__init__
在具有此元类的类被定义时调用。我们只需将名称和对象添加到元类中的注册表dict中。这样你以后就可以直接查了。在顺便说一句,工厂实例化了类,所以这个名称不适合只返回类的函数。在
相关问题 更多 >
编程相关推荐