繁体   English   中英

在 Python 中枚举实例方法

[英]Enumerate instance methods in Python

我想列举一个类中的一些实例方法。 operate函数需要使用foo1 , foo2 ,.. 作为Foo.FOO1 , Foo.FOO2 ,.. 。

class Machine:
    def __init__(self):
        self.operate()

    def foo1(self):
        pass
    def foo2(self):
        pass
    ..

    class Foo(Enum):
        FOO1 = Machine.foo1 # Machine is not defined
        FOO2 = Machine.foo2 # Machine is not defined
        ..
    
    def operate(self):
        # use self.Foo.FOO1, self.Foo.FOO2,..

我不知道如何定义枚举类。

@giannisl9 提出的解决方案有问题,尽管乍一看它显然有效,但仔细检查会发现Enum已损坏:

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'

基于@Epic Programmer 的答案 - 因为最初的问题仅声明为定义Enum以运行实例方法的要求 - 给定应用程序,在__init__或其他方法中组织过程就足够了:

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

但是,据我了解, Enum应该在类内部是完全有意义的,因为从本体上讲,它涉及编码/缩写一组适合于类的所有实例的状态。 这很有意义!

__init__中将其声明为self实例常量没有多大意义。 相反,它应该用作符号类常量,允许对可能与实例相关的所有内容进行编码。

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

或者,这大概就是您正在寻找的东西:

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)

我希望这有帮助。

假设 Foo 类中所有不以_开头的方法都是您要使用的方法,只需遍历 Foo 类的内容并获取匹配的方法的属性:

class Machine:
    def operate(self):
        for attribute in dir(self.Foo):
            if attribute[0] != "_":
                getattr(self.Foo, attribute)()

以下如何在类范围内使用类名? 对我来说最有意义的是,在 init 方法中定义枚举似乎是要走的路。

class Machine:
    def __init__(self):
        class Foo(Enum):
            FOO1 = self.foo1
            FOO2 = self.foo2
            ..
        self.Foo = Foo 
        self.operate()

    def foo1(self):
        pass

    def foo2(self):
        pass
    ..

    def operate(self):
        #self.Foo.FOO1(), self.Foo.FOO2(),.. availabe
        #self.Foo holds the enumeration

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM