有没有办法在python中为类的所有实例运行一个方法?

时间:2013-11-16 16:13:54

标签: python class methods

示例代码:

>>> class MyClass(object):
        def __init__(self, x, y):
            self.x = x
            self.y = y
        def power(self):
            print(self.x**self.y)
        def divide(self):
            print(self.x/self.y)

>>> foo = MyClass(2, 3)
>>> bar = MyClass(4, 7)
>>> 
>>> foo.power()
8
>>> bar.divide()
0.5714285714285714

每当我以前在Python中使用类时,我就会分别为每个实例运行该方法(参见上文)。我只是想知道如果有一种方法可以同时为该类的所有实例运行相同的方法,因为如果你有20个左右的实例,它可能会有点烦人。我在考虑这样的事情:

>>> allinstances.power()
8
16384

有没有办法做到这一点?

6 个答案:

答案 0 :(得分:4)

通常不会。但是,你可以让你的班级能够做到这一点:

GLOBAL_MYCLASS_LIST = []

class MyClass(object):

    def __init__(self, x, y):
        GLOBAL_MYCLASS_LIST.append(self)
        self.x = x
        self.y = y

    def power(self):
        print(self.x**self.y)

    def divide(self):
        print(self.x/self.y)

a = MyClass(2, 3)
b = MyClass(4, 7)
all_powers = [i.power() for i in GLOBAL_MYCLASS_LIST]

当然,您也可以在不将其烘焙到课堂中的情况下这样做,这对于您可能拥有不同MyClass个集合的大多数情况来说可能更为清晰:

myclass_list = []

class MyClass(object):

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def power(self):
        print(self.x**self.y)

    def divide(self):
        print(self.x/self.y)

myclass_list.append(MyClass(2, 3))
myclass_list.append(MyClass(4, 7))
all_powers = [i.power() for i in myclass_list]

答案 1 :(得分:3)

不确定。在创建实例时将实例放入列表中,然后遍历列表并在每个实例上调用方法。此外,您应该更改方法以返回而不是打印结果,因为这样更灵活。这样,您可以将结果存储在列表中,将它们写入文件,使用它们进行进一步计算,打印它们。

instances = [MyClass(2, 3), MyClass(4, 7)]
results   = [x.power() for x in instances]

答案 2 :(得分:3)

class MyClass(object):

    instancelist = []

    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.instancelist.append(self)

    def power(self):
        print(self.x ** self.y)

    def divide(self):
        print(self.x / self.y)


foo = MyClass(2, 3)
bar = MyClass(4, 7)

[instance.power() for instance in MyClass.instancelist]

将输出:

8
16384

这样,您不需要存储在类定义之外的任何全局变量或占位符。

答案 3 :(得分:2)

从你的问题来看,我相信你也会想要一点动力。下面的内容可能有所帮助:

我添加了一个名为printBoth()的函数用于演示。

注意:下面的Python 2.x代码

class MyClass(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def power(self):
        print "power",self.x**self.y
    def divide(self):
        print "divide", self.x/self.y
    def printBoth(self):
        print "x: ", self.x
        print "y: ", self.y

class Test:
    def __init__(self, items):
        self.items = items
    def __getattr__(self, key):
        def fn():
            return [getattr(x,key)() for x in self.items]
        return fn

foo = MyClass(2, 3)
bar = MyClass(4, 7)

t = Test([foo,bar])

t.power()
t.divide()
t.printBoth()

输出:

power 8
power 16384
divide 0
divide 0
x:  2
y:  3
x:  4
y:  7

注意:代码可能会在很多情况下中断,您需要在实际实现中执行其他检查。


重要的部分在这里:

def __getattr__(self, key):
    def fn():
        return [getattr(x,key)() for x in self.items]
    return fn

Test实例上的任何函数调用时调用上述函数。返回的是不带参数的函数。该函数在所有实例上运行,并在self.items上的每个上调用相同的函数(这是您要调用函数的所有实例的列表)。结果以列表形式返回。

答案 4 :(得分:1)

只需使用循环:

foo = MyClass(2, 3)
bar = MyClass(4, 7)
for i in [foo, bar]:
   i.power()

如果您不确定所有实例都有该方法,请使用hasattr检查:

for i in list_of_instances:
   if hasattr(i, 'power'):
       i.power()

答案 5 :(得分:1)

我认为所有答案都有效,具体取决于用例。我认为,如果在app / program的分离部分中使用此类,则不希望依赖于之前声明的GLOBAL_MYCLASS_LIST(如@amber建议的那样)。您可能希望确保此变量存在并将其声明为Class Variable,并将compute_all作为Class method or even as a static method@staticmethod装饰器(我认为与特定用例不太相关)。

同样,我要强调这是一个非常具体的用例,并不常见。所以你应该在做之前考虑你的设计,而不要使用其他答案中提供的更直接的pythonic方式。

我还想向您推荐这个关于python类Pycon lecture的好视频,它可以很好地解释这个(甲板是here。)