简体   繁体   English

在 __getattribute__ 的返回值上调用方法

[英]call method on returned value of `__getattribute__`

I'm trying to programmatically call a particular method on attributes of a class, Outer calling the step method on the Inner attribute below.我正在尝试以编程方式调用 class 的属性上的特定方法, Outer在下面的Inner属性上调用step方法。 I need to do this because I'll have a variable number of attributes that implement the step method.我需要这样做,因为我将有数量可变的属性来实现 step 方法。

class Inner(object):
    def __init__(self):
        self.a = 0
    def step(self):
        self.a += 1

class Outer(object):
    def __init__(self):
        self.inner = Inner()
        self.step_attrs = []
        for attr in self.__dir__():
            if hasattr(self.__getattribute__(attr), 'step'):
                self.step_attrs.append(attr)
    def step(self):
        for attr in self.step_attrs:
            self.__getattribute__(attr).__getattribute__('step')()
        

outer = Outer()
print(outer.inner.a)
outer.step()
print(outer.inner.a)

This code throws: TypeError: expected 1 argument, got 0这段代码抛出: TypeError: expected 1 argument, got 0

If I changed the last line in the Outer().step method to如果我将Outer().step方法的最后一行更改为

self.__getattribute__(attr).__getattribute__('step')(self.__getattribute__(attr))

it fails with TypeError: step() takes 1 positional argument but 2 were given它失败并出现TypeError: step() takes 1 positional argument but 2 were given

if i got you right, you need somethig like this:如果我没看错,你需要这样的东西:

class Inner(object):
    def __init__(self):
        self.a = 0
    def step(self):
        self.a += 1

class Outer(object):
    def __init__(self):
        self.inner = Inner()
        self.step_attrs = [i for i in self.__dict__ if hasattr(self,"step")]
        print(self.step_attrs)

    def step(self):
        for j in self.step_attrs:
            getattr(self,j).step()

outer = Outer()
print(outer.inner.a)
outer.step()
print(outer.inner.a)

Result:结果:

['inner']
0
1

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

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