在 Python 中循环 Class 中的函数

Loop through functions in a Class in Python

我有以下简化代码:

class States:
    def __init__(self):
        pass

    def state1(self):
        a = 2*10
        return a

    def state2(self):
        a = 50/10
        return a

class Results:
    def __init__(self):
        pass

    def result(self):
        states = States()
        
        x = []
        
        for i in [state1,state2]:
            state_result = states.i()
            x.append(state_result)
            
        return x

我想遍历 class“状态”中的每个函数。当然

for i in [state1,state2]

will return “name 'state1' is not defined”,但我希望它能告诉我我要实现的目标。

您可以使用dir() to get the name of the functions of a class. You can then use getattr()调用函数。

class States:
    def __init__(self):
        pass

    def state1(self):
        a = 2*10
        return a

    def state2(self):
        a = 50/10
        return a

state = States()
for func in dir(States):
    if func.startswith('__'):
        continue
    print(func)
    print(getattr(state, func)())

会输出

state1
20
state2
5.0

你可以这样做:

def result(self):
        states = States()
        
        x = []
        
        for i in [states.state1,states.state2]: # changed state1 to states.state1 and so on
            state_result = i()
            x.append(state_result)
            
        return x

我想你可以使用 lambda。在这里,我为你做了一个简单的例子。

def foo(text):
    print(text)
        
            
a = [lambda: foo("hey"), lambda: foo("boo")]
for i in a:
    i()

结果:

hey
boo

你的情况,你应该过来:

for i in [lambda: state1(), lambda:state2()]:
    state_result = i()
    x.append(state_result)

但是如果你问我的意见,重要的是要告诉你,通过列表调用函数不是一种健康的方式。一种软件语言通常有多种情况的解决方案;但在这种情况下,我认为你的观点是错误的。通过搞乱内置技术并试图找到一些秘密技巧来工作不是建议的事情。

您可以通过 class' 字典获取 class 个州的成员:

States.__dict__

这将为您提供 class 的所有属性和功能:

{'__module__': '__main__', '__init__': <function States.__init__ at 0x00000183066F0A60>, 'state1': <function States.state1 at 0x00000183066F0AF0>, 'state2': <function States.state2 at 0x000001830 ...

您可以将其过滤到列表理解字典中,以不包括 dunders 作为:

[funcname for funcname in States.__dict__ if not (str.startswith('__') and str.endswith('__'))]

这将 return 您的成员函数列表为:

['state1', 'state2']

然后创建一个 States 对象为:

states = States()

完成整个计算:

for funcname in [funcname for funcname in States.__dict__ if not (funcname.startswith('__') and funcname.endswith('__'))]:
    x.append(States.__dict__[funcname](states))

更好的是,将其理解为:

[States.__dict__[funcname](states) for funcname in States.__dict__ if not (funcname.startswith('__') and funcname.endswith('__'))]

应用此方法后您的答案是:[20, 5.0]

或获取 functionName 和 returnValues 的字典作为理解:

{funcname: States.__dict__[funcname](states) for funcname in States.__dict__ if not (funcname.startswith('__') and funcname.endswith('__'))}

这会给你一个输出:

{'state1': 20, 'state2': 5.0}

最简单的方法是“注册”您的状态方法。像这样的东西:

class States():
    states = []
    def register_state(cache):
        def inner(fn):
            cache.append(fn)
        return inner
    
    @register_state(states)
    def state1(self):
        a = 2*10
        return a
        
    @register_state(states)
    def state2(self):
        a = 50/10
        return a

那么你的结果class可以做到

class Results:
    def __init__(self):
        pass
    
    def result(self):
        states = States()
        
        x = []
        
        for i in states.states:
            state_result = i(states)
            x.append(state_result)
            
        return x