Python 字段的默认值

Python 字段的默认值,python,object,enums,Python,Object,Enums,在python脚本中,从对象访问字段时遇到问题。基本上可以归结为以下一段代码: from enum import Enum class AbstractFoo: def __init__(self, foo='works', bar='nope'): self.foo = foo self.bar = bar class Foo(Enum): test = AbstractFoo('bla', 'tada') 因此,在python控制台中,我

在python脚本中,从对象访问字段时遇到问题。基本上可以归结为以下一段代码:

from enum import Enum

class AbstractFoo:
    def __init__(self, foo='works', bar='nope'):
        self.foo = foo
        self.bar = bar

class Foo(Enum):
    test = AbstractFoo('bla', 'tada')
因此,在python控制台中,我尝试使用以下命令访问枚举元素:

Foo.test.foo
我希望它打印我的'bla',这是我传递给构造函数的值(或者至少它应该打印'works',这是我指定的默认值)

我真正得到的是

AttributeError: 'Foo' object has no attribute 'foo'
到现在为止,您可能已经知道我对python非常陌生,尤其是python中的概念对象(我主要用Java编写代码,这可能会导致我对python中对象行为的一些误解)

我想我能做到的是:

Foo.test.foo = 'whatever'
并以这种方式为foo赋值。但在执行此操作时,我还可以为构造函数中甚至没有指定的字段赋值,例如:

Foo.test.noField = 'shouldn't even exist'
我完全不明白,它也会很好地工作

如果能澄清一下对象在python中是如何工作的和/或如何在python中实现类的枚举,我将非常高兴


编辑:如果我从Enum中删除继承,代码的行为显然与我所希望的一样。

这可能会让人非常困惑,因为您实际上是在说
test
是某种东西,然后它就不再是了。这是因为它是一种特殊的类,它接受它的所有成员并将它们“转换”为类的实例。因此,
test
的类型不再是
AbstractFoo
,而是
Foo
。但是,您可以使用
value
属性返回分配给枚举实例的原始值:

from enum import Enum

class AbstractFoo:
    def __init__(self, foo='works', bar='nope'):
        self.foo = foo
        self.bar = bar

class Foo(Enum):
    test = AbstractFoo('bla', 'tada')

print(Foo.test.value.foo)

>>> bla

正如@jdehesa所指出的,
Enum
成员是其父
Enum
类的实例。如果您需要它们也是某个其他类的实例,只需从该类继承即可:

class Foo(AbstractFoo, Enum):
    test = 'bla', 'tada'

请注意,您不再需要直接调用
AbstractFoo

您必须有一个枚举吗?如果您没有从
Enum
继承
Foo
,那么代码的工作方式就是您所期望的!多谢各位!但是enum有什么问题呢?当我不使用enum时,这不是更像是属于类Foo的静态字段(使用Java行话)而不是enum吗?这与我要做什么并不重要,但我更喜欢理解我的代码为什么工作(:没有enum,是的,它类似于静态字段,因为我理解静态字段。我明白你的意思了!非常感谢你的解释!正如第一位发表评论的人指出的那样,我的案例根本不需要enum。所以我唯一不明白的是,你什么时候会在python中实际使用enum?我的意思是它所做的一切都是ba给你的类的实例指定类型Enum,并强制你通过.value访问字段。那么,为什么不干脆离开Enum的继承,开心一点呢?@destive
Enum
确实只是一件方便的事情(就像Python中的大多数事情一样,似乎是8D)。它不允许(有点)直接创建类实例并使值比较更安全(有点)。它还允许您迭代现有值。但是,它不提供开关/大小写完整性检查(首先需要开关语句)之类的功能,因此其优势是有限的。