Is there a way to run a method for all instances of a class in python?

Example code:

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

Whenever I used classes in Python previously, I just ran the method for each instance separately (see above). I was just wondering If there was a way to run the same method for all the instances of that class at once, because it could get a bit annoying, if you have 20 or so instances. I'm thinking of something like this:

>>> allinstances.power()
8
16384

Is there a way of doing this?

Answers


Not usually. You could make your class be capable of that, however:

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]

Of course, you could also do that without baking it into the class, which is probably cleaner for most cases where you might have different sets of MyClasses:

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]

Sure. Put the instances in a list as you create them, then iterate over the list and call the method on each instance. Also, you should change your methods to return rather than print their results, as this is much more flexible. That way you can store the results in a list, write them to a file, do further calculations with them, or print them.

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

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]

will output:

8
16384

This way you do not need any global variables or placeholders that are stored outside of the class definition.


From your question, I believe you would want a bit of dynamism too. Something like below could help:

I have added a function called printBoth() for demonstration.

Note: Python 2.x code below

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

Output:

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

Note: The code can break on many occasions, you neeed to perform additional checks in real implementation.


The important part is here:

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

The above function is invoked upon any function call on the Test instance. What is returned is function that takes no arguments. The function runs over all the instances, and invokes the same function on every item on self.items (which is the list of all the instances you want to invoke your function on). The results are returned as a list.


Need Your Help

How to get initial uri of a redirected http request using mikeal/request

node.js http httprequest

Using node.js mikeal/request i do a bunch of simultaneous requests. The requests allow redirects.

How can i remove duplicates from this Sql Server Table?

sql sql-server-2008 duplicates

I have a single table in the Sql Server 2008 r2 DB. Every few seconds I import data into this table. At one point, the import was failing, so it was constantly importing the same data, creating

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.