gpt4 book ai didi

python - 在创建时将属性附加到类

转载 作者:太空宇宙 更新时间:2023-11-04 10:52:46 26 4
gpt4 key购买 nike

我有一堆持久化在 ZODB 中的类。所有类都必须共享一些索引功能,而且它们都定义了很多属性。这些属性是在带有描述符的类级别上定义的,以便能够拦截写入它们以进行验证并检查数据库中的重复项。为此,每个类都有一个自动维护的属性列表 _properties。它们还包含 _indices 和一些其他功能,我不想自己将这些功能复制到每个元素类(大约 10 个左右)。

考虑以下代码:

class BaseElement(object):
_properties = None

class ElementFlavour1(BaseElement):
_properties = 'a', 'b', 'c'

....

class ElementFlavourN(BaseElement):
_properties = 'e', 'f', 'g'

for item in locals():
if issubclass(item, BaseElement):
item._v_properties_set = set(item._properties) if item._properties else set()

因此,它基本上完成了它应该做的事情:我需要线性迭代 _properties,但我也想快速查找,如果类中存在某些属性。尽管如此,我不想重复自己并为 BaseElement 的每一种风格明确指定这个集合。

当前的解决方案有效,但我认为它是一个丑陋的 hack,并希望摆脱它。例如。其他模块中 BaseElement 的子类无法正确设置它们的属性。玩弄 __new__ 似乎也是错误的方式,因为它不会拦截类构造,而是拦截实例化。那么,如何正确地做到这一点?

附言我知道 OrderedDict,但这不是我要找的。我想以一种干净的方式连接到类创建过程并在那里附加任意功能。

最佳答案

你可以用元类做到这一点:

class BaseType(type):
def __init__(cls, name, bases, clsdict):
super(BaseType, cls).__init__(name, bases, clsdict)
setattr(cls,'_v_properties_set',
set(cls._properties) if cls._properties else set())

class BaseElement(object):
__metaclass__ = BaseType
_properties = None

class ElementFlavour1(BaseElement):
_properties = 'a', 'b', 'c'

class ElementFlavourN(BaseElement):
_properties = 'e', 'f', 'g'

print(ElementFlavourN._v_properties_set)
# set(['e', 'g', 'f'])

您也可以使用类装饰器来完成此操作,但是您必须单独装饰 BaseElement 的每个子类。元类是继承的,所以你只需要定义一次。

关于python - 在创建时将属性附加到类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12651557/

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