statespace
statespace

Reputation: 1664

Python: reference to other instances of class objects

Idea is that class contains several instances and when one of instances is called for some method, it checks for all other existing instances of the same class for some value. Or, perhaps, it will be easier to formulate in code:

class foo:
    def __init__(self, value):
        self.value = value

    def getvalues(self):
        self.magichappenshere = '?'

Joe = foo(5)
Bob = foo(4)
Jon = foo(3)

Jon.getvalues()

#expected output:
#12

How to refer to other instances without explicitly calling them? I was thinking of giving additional name attribute in __init__ which corresponds to instance name as in Joe = foo("Joe", 5) and accumulates in some sort of outside list. But that didn't seem like a very good solution. What would be THE way to do this?

Upvotes: 0

Views: 105

Answers (2)

Martijn Pieters
Martijn Pieters

Reputation: 1125388

You can 'register' your instances with your class, in a class attribute:

class foo:
    _instances = []

    def __init__(self, value):
        self.value = value
        foo._instances.append(self)

    def getvalues(self):
        return sum(instance.value for instance in foo._instances)

Note that this'll keep instances around forever! You'd have to use weak references to avoid that:

from weakref import WeakSet

class foo:
    _instances = WeakSet()

    def __init__(self, value):
        self.value = value
        foo._instances.add(self)

    def getvalues(self):
        return sum(instance.value for instance in foo._instances)

The WeakSet() keeps track of objects without keeping them alive; if any other references to an instance drop to 0, the instance is cleared from memory and the foo._instances weak set will simply stop listing it.

Demo:

>>> from weakref import WeakSet
>>> class foo:
...     _instances = WeakSet()
...     def __init__(self, value):
...         self.value = value
...         foo._instances.add(self)
...     def getvalues(self):
...         return sum(instance.value for instance in foo._instances)
... 
>>> Joe = foo(5)
>>> Bob = foo(4)
>>> Jon = foo(3)
>>> Jon.getvalues()
12
>>> del Joe
>>> Jon.getvalues()
7

Upvotes: 2

Padraic Cunningham
Padraic Cunningham

Reputation: 180550

Use a class attribute to keep track of the sum of the values

class foo:
    value_sum = 0
    def __init__(self, value):
        self.value = value
        foo.value_sum += value

    def getvalues(self):
        return  foo.value_sum

In python you don't need a getter so I would just access the class attribute directly:

class foo:
    value_sum = 0 
    def __init__(self, value):
        self.value = value
        foo.value_sum += value


Joe = foo(5)
Bob = foo(4)
Jon = foo(3)

print foo.value_sum

Upvotes: 1

Related Questions