The solution proposed by @giannisl9 is bugged, although it apparently works at first sight, a closer inspection reveals the Enum
is broken:
from enum import Enum
class Machine:
def __init__(self):
class Foo(Enum):
FOO1 = self.foo1
self.foo = Foo
self.operate()
def foo1(self):
pass
def operate(self):
# breaks Enum contract, breaks syntax, breaks functionality...
self.foo.FOO1() # Enum member is NOT available! Method of class Machine bound in its place.
print(type(self.foo)) # {type}<class'enum.EnumMeta'> - Enum 'Foo'
print(type(self.foo.FOO1)) # {type} <class 'method'> - should be Enum member
print(type(self.foo.FOO1.name)) # {AttributeError}'function'object has no attribute 'name'
print(type(self.foo.FOO1.value)) # {AttributeError}'function'object has no attribute 'value'
Building on the answer by @Epic Programmer -since the original question only stated as requirement defining an Enum
to run instance methods- given the application, organizing procedures in the __init__
or other methods, could suffice:
from inspect import ismethod
from inspect import isbuiltin
class Machine(object):
def operate(self):
for method in self.__dir__():
if ismethod(getattr(self, method)) \
and not isbuiltin(getattr(self, method)) \
and '__' not in method \
and 'operate' != method: # delete this to see a recursion
self.__getattribute__(method)() # after much filtering runs the method
def __init__(self):
self.operate()
def foo1(self):
print("drinks at bar1")
However, as I understand the question, it makes perfect sense the Enum
should be internal to the class, since ontologically it pertains to encode/abbreviate a set of states proper to all instances of the class. That makes lots of sense!
It doesn't make much sense declaring it inside the __init__
as a self
instance constant. Instead, it should be used as a symbolic class constant allowing to encode everything that in common may pertain to the instances.
from enum import Enum
class Machine:
class Foo(Enum):
# you could comma separate any combination for a given state
FOO1 = "foo1"
FOO2 = "foo2"
def __init__(self, arg_foo):
self.foo = arg_foo
self.operate()
self.all_operations()
def foo1(self):
print('drinks at bar1')
def foo2(self):
print('drinks at bar2')
def all_operations(self):
for one_member in Machine.Foo:
self.__getattribute__(one_member.value)()
def operate(self):
self.__getattribute__(str(self.foo.value))()
go_bar1 = Machine(Machine.Foo.FOO1)
go_bar2 = Machine(Machine.Foo.FOO2)
go_bar1.all_operations() # bar crawl
Or perhaps this is, approximately, what you're looking for:
from enum import Enum
class Machine:
def __init__(self, receive: Enum):
for one in receive.value:
if one is not None:
one(self) # Zen of Python
def foo1(self):
print('drinks at bar1')
def foo2(self):
print('drinks at bar2')
class Runner(Enum):
FOO1 = getattr(Machine, 'foo1'), getattr(Machine, 'foo2')
FOO2 = getattr(Machine, 'foo2'), None
first = Machine(Runner.FOO1)
second = Machine(Runner.FOO2)
I hope this helps.