Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default value for fields

I have problem accessing fields from an object in a python script I did. Basically it boils down to this little piece of code:

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')

So when in the python console I try to access an element of my enum with:

Foo.test.foo

I would expect it to print me 'bla' which is the value I pass to the constructor (or at least it should print 'works' which would be the default value I've assigned).

What I actually get is

AttributeError: 'Foo' object has no attribute 'foo'

you can probably tell by now that I'm pretty new to python and especially the concept objects in python (I mostly write code in Java which might lead to some missconceptions from my part about the behaviour of objects in python).

What I figured out though is that I can do:

Foo.test.foo = 'whatever'

and assign a value to foo in this way. But when doing this I can also assign a value to a field I haven't even specified in the constructor such as:

Foo.test.noField = 'shouldn't even exist'

and it will work just as fine which I don't understand at all.

I would be really glad about some clarification how objects work in python and/or how I could realize an enum of a class in python.

EDIT: Apparently the code behaves the way I want it to if I remove the inheritance from Enum.

like image 753
TropicalSpore Avatar asked Jul 05 '26 15:07

TropicalSpore


2 Answers

That can be quite confusing, since you are literally saying that test is something and then it is not anymore. That is because Enum is a special kind of class that takes all of its members and "converts" them into instance of the class. So the type of test is not AbstractFoo anymore, but instead Foo. However, you can get back the original value assigned to the enum instance with the value property:

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
like image 105
jdehesa Avatar answered Jul 07 '26 04:07

jdehesa


As @jdehesa noted, Enum members are instances of their parent Enum class. If you need them to also be instances of some other class simply inherit from it as well:

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

Note that you no longer need to call AbstractFoo directly.

like image 40
Ethan Furman Avatar answered Jul 07 '26 05:07

Ethan Furman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!