-1

this is my code

#coding:utf8 

from enum import Enum


class Color(Enum):
    red=1
    green=2
    black=3


Color.red.price=30.0
Color.black.price=40.0
Color.green.price=40.0

Color.green.xxx = True

why the color.red has this attribute ,such as price or xxx or anything? Thanks for you answer

kunpengku
  • 117
  • 9
  • I would expect this to cause an error. It shouldn't have those attributes. – Carcigenicate Aug 02 '17 at 04:26
  • @Carcigenicate Funnily enough, I tried this and it works. – cs95 Aug 02 '17 at 04:28
  • @cᴏʟᴅsᴘᴇᴇᴅ I tried it, but QPython on my phone isn't running a new enough version to have the module. I looked over the docs and can't find a price field. Does python allow attributes to be added on the fly, JS-style with a special tweak? – Carcigenicate Aug 02 '17 at 04:29
  • 2
    You're just adding attributes to it. Nothing fancy there. – jhpratt Aug 02 '17 at 04:30
  • @Carcigenicate Yes, it would seem there is no protection against this sort of thing. – cs95 Aug 02 '17 at 04:31
  • @cᴏʟᴅsᴘᴇᴇᴅ The docs suggest that Enums are special. "Even though we use the class syntax to create Enums, Enums are not normal Python classes. See How are Enums different? for more details." My Python is too rusty to understand wtf it's talking about after that though. – Carcigenicate Aug 02 '17 at 04:32
  • Wait, my python must be really rusty. I just created a new bare class and was able to do this. This doesn't seem to have anything to do with Enums. Never knew Python allows attributes to be added at runtime. – Carcigenicate Aug 02 '17 at 04:36
  • https://stackoverflow.com/questions/2827623/python-create-object-and-add-attributes-to-it – Carcigenicate Aug 02 '17 at 04:40
  • 1
    The type of `Color.red` is an ``, which is an object, why does adding an attribute seem fancy? @Carcigenicate python is a dynamic language, you can add attributes to any object even functions: `def f(): pass; f.a = 10` is perfectly legal. – AChampion Aug 02 '17 at 04:41
  • @AChampion Wow. Not sure how I missed that during the year that I wrote Python. Good to know! – Carcigenicate Aug 02 '17 at 04:42
  • @AChampion you're right – kunpengku Aug 02 '17 at 04:55

3 Answers3

1

Color.red has a price attribute because you gave it one. The only (mostly) immutable parts of an Enum member are its name and value.

Note that Color.red does not have an xxx attribute as you only assigned that one to Color.green.


If you really want to disallow adding extra attributes at run-time, please see Python enum prevent invalid attribute assignment.

Ethan Furman
  • 63,992
  • 20
  • 159
  • 237
0

In this example, the Color class objects don't have such attribute.

What's happening here is that you are creating those attribute, which could then be used. Apparently, python being dynamic and stuff allows such a thing.

If we see objects as arrays of values and references, what you'd be doing here is appending another value (or reference) to the current object.

I did a quick and dirty example using this online interpreter :

from enum import Enum

class names(Enum):
    Paul=1
    Robert=2,
    Jean=3,
    Charles=4

names.Paul.price = 25
print(names.Paul.price)  # works, as we just added the price poperty.
print(isinstance(names.Paul, names))  # returns true, we don't lose property.
print(names.Robert.price)  # AttributeError, we didn't add it. 
Alceste_
  • 592
  • 4
  • 13
  • Omg, it was getting late and I realised I had described behavior without explaining much. Will probably edit later on. – Alceste_ Aug 02 '17 at 12:11
0

This is just like any other object. You can add new attributes to an class object(those attributes belongs only to the object)

class A:
  foo1="bar"

a=A()
a.foo2="bar2"
print(a.foo2)
print(A.foo1) 
print(A.foo2) # gives an attribute error

In case of enum

 from enum import Enum
   class A(Enum): 
..   a="enum" 
.. 

each member is an Enum object

   dir(A.a)
=> ['__class__', '__doc__', '__module__', 'name', 'value']

   dir(Enum)
=> ['__class__', '__doc__', '__members__', '__module__']

Hence just like any other class object you can add attribute to the object

A.a.foo1="bar1"
SarathSprakash
  • 4,614
  • 2
  • 19
  • 35