Python2.x-在同一个类中创建类的静态实例

Python2.x-在同一个类中创建类的静态实例,python,class,static,visibility,definition,Python,Class,Static,Visibility,Definition,我正在尝试用python编写一个“枚举类”。我目前遇到的一个小麻烦是无法在枚举类中定义枚举值。也就是说,我可以做到: class Fruit: def __init__(self, name): self.name = name class Fruits(Enum): Apple = Fruit("apple") 但我想这样做,或类似的易读等效: class Fruit(Enum): def __init__(self, name):

我正在尝试用python编写一个“枚举类”。我目前遇到的一个小麻烦是无法在枚举类中定义枚举值。也就是说,我可以做到:

class Fruit:
    def __init__(self, name):
        self.name = name

class Fruits(Enum):
    Apple = Fruit("apple")
但我想这样做,或类似的易读等效:

class Fruit(Enum):
    def __init__(self, name):
        self.name = name

    Apple = Fruit("apple")
不幸的是,我遇到以下错误: 未定义名称“水果”


在这种情况下,可见性的规则是什么?有什么鲜为人知的Python技巧可以帮助我吗?我更喜欢可以在Enum元类中编写的东西,因为这样可以减少用户使用的麻烦。

您可以创建一个元类,它可以完成以下简单的操作:

class MetaEnum(type):
    def __new__(cls, class_name, parents, attrs):
        def __init__(self, name=None):
            if name is not None: self.name = name
        attrs['__init__'] = __init__
        Klass = type.__new__(cls, class_name, parents, attrs)
        if 'instances' in attrs:
            for name in attrs['instances']:
                setattr(Klass, name.capitalize(), Klass(name))
            del Klass.instances # clean up
        return Klass

class Fruit(object):
    __metaclass__ = MetaEnum
    instances = ('apple', 'banana', 'cranberry')

for attr_name in dir(Fruit):
    if not attr_name.startswith('_'):
        attr = getattr(Fruit, attr_name)
        if type(attr) is Fruit:
            print('Fruit.{}, is a Fruit named {}'.format(attr_name, getattr(attr, 'name')))
        else:
            print('Fruit.{}, is a {}'.format(attr, type(attr)))
输出:

Fruit.Apple,是一种名为Apple的水果
香蕉,是一种叫做香蕉的水果
蔓越莓,是一种叫做蔓越莓的水果

Enum的元类没有显示,因为我认为它非常不相关。这是因为
class
直到您到达它的块的末尾才完成定义。在类定义之后,您可以执行
Fruit.Apple=Fruit(“Apple”)
创建实例并将其存储为类属性。Enum的元类不显示,因为它不相关,但您想知道如何修改它以解决问题。unshown元类目前做什么?@martineau该元类添加了
\uuuu iter\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
支持,因此我。至于在类定义之后添加
Fruit.Apple=
,这是可行的,也没那么糟糕。我会找更好的,也许我能找到:)不错,如果我读对了,它能满足我的需要。我没有想到这条路线。可怜的语法,我会努力一点。。。绝对+1。你想要实例吗?好的,请参阅我对您更新的问题的更新答案。Re:语法,如果您在全局模块级别定义
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu=MetaEnum
,它将成为默认值并应用。