gpt4 book ai didi

python - 动态基类和工厂

转载 作者:行者123 更新时间:2023-11-28 19:34:37 25 4
gpt4 key购买 nike

我有以下代码:

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”的具体子类并创建它。

这是有效的方法还是我有什么误解和做错了?

最佳答案

我会用装饰器来做这件事。此外,将实体 -> 子类映射存储在字典中可以让您用字典查找替换线性扫描。

class EntityBase(object):
_entity_ = None
_entities_ = {}

@classmethod
def factory(cls, entity):
try:
return cls._entities_[entity]
except KeyError:
raise FactoryError(tag, "Unknown entity")

@classmethod
def register(cls, entity):
def decorator(subclass):
cls._entities_[entity] = subclass
subclass._entity_ = entity
return subclass
return decorator

factory = EntityBase.factory
register = EntityBase.register

@register('Smith')
class Smith(EntityBase):
def __init__(self, a, b):
self.a = a
self.b = b

s = factory('Smith')(1, 2)

如果您只是使用它来实现线性扫描,我不确定 __entity__ 属性是否真的对您有用。我把它留在里面了,但如果你把它去掉,那么与实体相关的类甚至不需要从 EntityBase 继承,你可以将它重命名为 Registry 之类的东西。这会使您的继承树变浅,并开启了在通过共同血统不相关的类上使用的可能性。

根据您的用例,更好的方法可能是

factory = {}

class Smith(object):
def __init__(self, a, b):
self.a = a
self.b = b
factory['Smith'] = Smith

class Jones(object):
def __init__(self, c, d):
self.c = c
self.d = d
factory['Jones'] = Jones

s = factory['Smith'](1, 2)
j = factory['Jones'](3, 4)

装饰器更漂亮,让我们对自己感觉良好和漂亮,但字典简单、有用且切中要点。这很容易理解,也很难出错。除非你真的需要做一些神奇的事情,否则我认为这就是要走的路。无论如何,你为什么要这样做?

关于python - 动态基类和工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3786762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com