如何使函数数组在python中可调用

时间:2019-07-16 06:03:07

标签: python

我正在尝试创建一个类A,该类基本上是对象B的列表。 我希望能够在A中自动调用方法 返回B中相应方法的列表:

A.method(x)= [A中B的B.method(x)]

问题是我需要动态行为,所以B中的任何方法都是 由A自动“继承”,而无需对其进行硬编码。

我尝试使用lambda函数和exec(“”“ def ...”“”), 但似乎没有任何效果。这是一个尝试:

class A(object):

    def __init__(self,Bs):
        self.listOfBs = Bs[:]

        if self.listOfBs:
            for method_name in dir(self.listOfBs[0]):
                if not callable(getattr(self.listOfBs[0],method_name)):
                    continue

            f = lambda x: [getattr(B,method_name)(x) for B in self.listOfBs]
            setattr(self,method_name,f)

class B(object):
    def __init__(self,name):

        self.name = name

    def getName(self,x):
        return self.name+x

#So if I define:
a = A([B('x'),B('y'),B('z')])

#I would like to have: a.getName('W') = ['xW','yW','zW']
#However I get the error: TypeError: 'str' object is not callable

我认为应该有一种简单/优雅的方法来在python中实现上述行为,但是我找不到任何有效的方法。

2 个答案:

答案 0 :(得分:3)

您可以使用__getattr__使方法查找动态化

class A:
    def __init__(self, bs):
        self.bs = bs

    def __getattr__(self, method_name):
        def call(*args, **kw):
            return [getattr(b, method_name)(*args, **kw) for b in bs]
        return call

答案 1 :(得分:2)

非常感谢。我之前尝试过getattr,但是缺少一些步骤。 仅作记录,根据Glazner的建议,这里提供了一个可行的解决方案,该解决方案同时适用于属性和方法:

class A(object):

    def __init__(self,Bs):
        self.listOfBs = Bs[:]

    def __getattr__(self, attr):

        if not all(hasattr(b,attr) for b in self.listOfBs):
            raise AttributeError("Attribute %s not found." %attr)


        val = getattr(self.listOfBs[0],attr)
        if not callable(val):
            return np.array([getattr(b,attr) for b in self.listOfBs])

        def call(*args, **kw):
            return [getattr(b, attr)(*args, **kw) for b in self.listOfBs]
        return call        

class B(object):
    def __init__(self,name):

        self.name = name

    def getName(self,x):
        return self.name+x


a = A([B('x'),B('y'),B('z')])
a.name #Returns ['x','y','z']
a.getName('W')  #Returns ['xW','yW','zW']