On 31/05/2021 17:57, Colin McPhail via Python-list wrote:
Hi,

According to the enum module's documentation an Enum-based enumeration's 
members can have values of any type:

        "Member values can be anything: int, str, etc.."

You didn't read the fineprint ;)

"""
The rules for what is allowed are as follows: names that start and end with a single underscore are reserved by enum and cannot be used; all other attributes defined within an enumeration will become members of this enumeration, with the exception of special methods (__str__(), __add__(), etc.), descriptors (methods are also descriptors), and variable names listed in _ignore_
""""

Functions written in Python are descriptors and therefore cannot be used. Builtin functions aren't, leading to the following somewhat surprising difference:

>>> def foo(self): print("foo")

>>> class A(Enum):
        x = foo  # foo.__get__ exists -> foo is a descriptor
                 # the enum library assumes you are adding a
                 # method to your
                 # class, not an enumeration value.

        y = sum  # no sum.__get__ attribute -> function
                 # treated as an enumeration value.

>>> list(A)
[<A.y: <built-in function sum>>]
>>> A.x
<function foo at 0x012096A0>
>>> A.y
<A.y: <built-in function sum>>
>>> A.y.x()
foo

I defined one with functions as member values. This seemed to work as long as the functions 
were defined ahead of the enumeration's definition. However I then noticed that my 
enumeration class was a bit weird: even although I could reference the enumeration's 
members individually by name I couldn't iterate through the members in the normal fashion - 
it seemed to have no members. Also, calling type() on a member gave the result <class 
'function'> instead of the expected <enum 'enum name'>.

I am using Python 3.9.5 from python.org on macOS 11.4. Below is a small test 
script and its output. Are my expectations wrong or is there a problem with 
Enum?

Regards,
Colin

-------------------------------
from enum import Enum

def connect_impl():
     print("message from connect_impl()")

def help_impl():
     print("message from help_impl()")

class Command1(Enum):
     CONNECT = 1
     HELP = 2

class Command2(Enum):
     CONNECT = connect_impl
     HELP = help_impl

if __name__ == "__main__":

     def print_enum(cls, mbr):
         print(f"{cls.__name__}\n  type(): {type(Command1)}")
         print(f"  type of enum member: {type(mbr)}")
         print(f"  number of members: {len(cls)}")
         print("  enum members:")
         if len(cls) > 0:
             for c in cls:
                 print(f"    {c}")
         else:
             print("    <none>")
         print(f"  dir(): {dir(cls)}")

     member_1 = Command1.HELP
     print_enum(Command1, member_1)
     print()

     member_2 = Command2.HELP
     print_enum(Command2, member_2)
     print()
     print("call Command2 member: ", end="")
     member_2()
     print()

-------------------------------
(qt6) % python3 try_enum.py
Command1
   type(): <class 'enum.EnumMeta'>
   type of enum member: <enum 'Command1'>
   number of members: 2
   enum members:
     Command1.CONNECT
     Command1.HELP
   dir(): ['CONNECT', 'HELP', '__class__', '__doc__', '__members__', 
'__module__']

Command2
   type(): <class 'enum.EnumMeta'>
   type of enum member: <class 'function'>
   number of members: 0
   enum members:
     <none>
   dir(): ['__class__', '__doc__', '__members__', '__module__']

call Command2 member: message from help_impl()

(qt6) %
-------------------------------



--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to