我可以看到实现这项工作的多个障碍,这很可能是不可能的,但我想我至少会问...
所以,我有一个 AbstractEnumeratedConstantsGroup
类,不出所料,当它被子类化时,它会创建一个代表一组枚举常量的对象(例如 FLAVORS
,其值为 (' VANILLA', 'CHOCOLATE', 'STRAWBERRY')
其中 FLAVORS[0]
返回 'VANILLA'
, FLAVORS[1]
返回 'CHOCOLATE'
,FLAVORS.VANILLA
返回 0
,FLAVORS.CHOCOLATE
返回 1
等)它使用一个元类和一些其他的步骤,因此创建一个新常量组所需的全部是:
class FLAVORS(AbstractEnumeratedConstantsGroup):
_constants = ('VANILLA', 'CHOCOLATE', 'STRAWBERRY')
FLAVORS = FLAVORS()
我想进一步减少到:
@enumerated_constants_group
FLAVORS = ('VANILLA', 'CHOCOLATE', 'STRAWBERRY')
我不知道如何过去的问题是:
-
1. 没有很好的方法从装饰器代码的定义范围中获取对象的标签名称
2. 不能装饰不是类、方法或函数的东西
我考虑过使用工厂/构建器,但我不喜欢的是它需要在代码中重复组名,或者这些组具有无用的 __name__
值(在 __repr__
和 __str__
中使用)。例如:
FLAVOR = enumerated_constants_group('FLAVOR', ('VANILLA', 'CHOCOLATE', 'STRAWBERRY'))
或
FLAVOR = enumerated_constants_group(('VANILLA', 'CHOCOLATE', 'STRAWBERRY'))
# FLAVOR.__name__ becomes some unfriendly machine-generated string
作为装饰器想法的替代方案,是否可以从工厂方法中引用调用范围(通过内省(introspection)或隐式将其传递给函数),以便调用该方法将新创建的对象插入到使用给定名称调用 namespace ?例如:
enumerated_constants_group('FLAVOR', ('VANILLA', 'CHOCOLATE', 'STRAWBERRY'))
# I could now reference FLAVOR in any arbitrary scope that the method was called from
有什么我可以做的来实现我想要的吗?还有其他我没有想到的方法吗?
最佳答案
当您分配给一个裸名时,没有通用的方法来影响发生的事情(如 FLAVORS = ('VANILLA', 'CHOCOLATE', 'STRAWBERRY')
)。所以你想要的是不可能的。
也就是说,您可以编写一个元类,用它自己的一个实例替换返回的类,这样您就不需要在第一行中的最后一行 FLAVORS = FLAVORS(...)
例子。类定义本身就足以创建对象。
关于python - 在对象实例上使用装饰器(或其他一些模式)来生成类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11783715/