我可以看到制作这项工作的多个障碍,这可能是不可能的,但我想我至少会问......
所以,我有一个类AbstractEnumeratedConstantsGroup
,毫不奇怪,当子类创建了一个表示一组枚举常量的对象(ex 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')
我不知道如何过去的问题是:
我考虑过使用工厂/构建器,但我不喜欢的是它需要在代码中重复组名,或者组中有无用的__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
作为装饰器思想的替代方案,是否可以从工厂方法引用调用范围(通过内省或隐式地将其传递给函数),以便调用方法将新创建的对象插入到使用给定名称调用命名空间?例如:
enumerated_constants_group('FLAVOR', ('VANILLA', 'CHOCOLATE', 'STRAWBERRY'))
# I could now reference FLAVOR in any arbitrary scope that the method was called from
我能做些什么来实现我的目标吗?还有其他我没有想过的方法吗?
答案 0 :(得分:3)
没有一般方法可以影响分配给裸名称时发生的情况(如FLAVORS = ('VANILLA', 'CHOCOLATE', 'STRAWBERRY')
中所示)。所以你想要的是不可能的。
也就是说,您可以编写一个元类,用自己的实例替换返回的类,这样您在第一个示例中就不需要上一个FLAVORS = FLAVORS(...)
行了。类定义本身就足以创建对象。
答案 1 :(得分:2)
你看过http://code.activestate.com/recipes/413486/
吗?它允许您编写如下代码:
>>> from enum import enum
>>> FLAVORS = enum('VANILLA', 'CHOCOLATE', 'STRAWBERRY')
>>> print FLAVORS
enum (VANILLA, CHOCOLATE, STRAWBERRY)
>>> print FLAVORS.VANILLA
VANILLA
>>> f = FLAVORS.CHOCOLATE
>>> f in FLAVORS
True
>>> for f in FLAVORS:
... print f
...
VANILLA
CHOCOLATE
STRAWBERRY
答案 2 :(得分:0)
作为中间步骤,你可以做到
FLAVORS = type("FLAVORS",
(AbstractEnumeratedConstantsGroup,),
{_constants = ('VANILLA', 'CHOCOLATE', 'STRAWBERRY')})()
导致假装饰者
def enumerated_constants_group(*args):
AECG=AbstractEnumeratedConstantsGroup
t = type(args[0], (AECG,), dict(_constants=args[1:]))
return t()
FLAVORS = enumerated_constants_group('FLAVORS', 'VANILLA', 'CHOCOLATE', 'STRAWBERRY')
答案 3 :(得分:0)
除了函数/方法装饰器之外,你还有类装饰器(至少它们在python 2.4中),见http://www.python.org/dev/peps/pep-3129/
无论如何,我不确定这是你需要的。
我会使用工厂类(类型,值)作为args。
一个注意事项:如果你的代码是这样的,并且AbstractEnumeratedConstantsGroup没有添加任何功能,你为什么不只使用元组?
您可以使用以下内容定义constants.py模块:
FLAVOURS = ('VANILLA', 'CHOCOLATE', 'STRAWBERRY')
PETS = ('DOG', 'CAT', 'FISH')
然后使用代码中的那些元组:
import constants
for pet in constants.PETS:
print 'I have a ', pet
答案 4 :(得分:0)