Reputation: 12585
Suppose I have a Python class called Person
in file person.py
as follows:
class Person(object):
static_id = 0
instance_id = None
@staticmethod
def new_id():
Person.static_id += 1
return Person.static_id
def __init__(self):
self.instance_id = Person.new_id()
def __repr__(self):
return "<Person #%s>" % (self.instance_id)
Instantiating Person
works:
>>> a = Person()
>>> a
<Person #1>
>>> b = Person()
>>> b
<Person #2>
And I have another class called Thing
in file thing.py
as follows:
from person import Person
class Thing(object):
static_id = 0
instance_id = None
instance_creator = None
@staticmethod
def new_id():
Thing.static_id += 1
return Thing.static_id
def __init__(self, person):
self.instance_id = Thing.new_id()
self.instance_creator = person
def __repr__(self):
return "<Thing #%s created by %s>" % (self.instance_id, self.instance_creator)
Now, when I instantiate instances of Thing
I see the following:
>>> Thing(person=b)
<Thing #1 created by <Person #2>>
>>> Thing(person=b)
<Thing #2 created by <Person #2>>
>>> Thing(person=a)
<Thing #3 created by <Person #1>>
How can I create a (non-static) method Person.created_things()
that will return me all Things created by that instance of Person? I want:
>>> b.created_things()
[<Thing #1 created by <Person #2>>, <Thing #2 created by <Person #2>>]
But I cannot figure out how to do this without importing thing.Thing
into person.py
. Doing so would create a circular import reference. So how can I do it? In this case these are not Django classes.
Upvotes: 0
Views: 62
Reputation: 55479
You can do this without modifying the Person
definition in person.py
by dynamically modifying the person instance passed to Thing
:
from person import Person
class Thing(object):
static_id = 0
instance_id = None
instance_creator = None
@staticmethod
def new_id():
Thing.static_id += 1
return Thing.static_id
def __init__(self, person):
self.instance_id = Thing.new_id()
self.instance_creator = person
try:
person.created_things.append(self)
except AttributeError:
person.created_things = [self]
def __repr__(self):
return "<Thing #%s created by %s>" % (self.instance_id, self.instance_creator)
a = Person()
print a
b = Person()
print b
t1 = Thing(person=b)
print t1
t2 = Thing(person=b)
print t2
t3 = Thing(person=a)
print t3
print a.created_things
print b.created_things
output
<Person #1>
<Person #2>
<Thing #1 created by <Person #2>>
<Thing #2 created by <Person #2>>
<Thing #3 created by <Person #1>>
[<Thing #3 created by <Person #1>>]
[<Thing #1 created by <Person #2>>, <Thing #2 created by <Person #2>>]
Upvotes: 1
Reputation: 2491
Just add a couple of methods to Person
(and initialize self.things
in __init__
):
def __init__(self):
self.things = []
self.instance_id = Person.new_id()
def addThing(self, thing):
self.things.append(thing)
def created_things(self):
return self.things
And when you initialize Thing
, just add it to Person
.
def __init__(self, person):
self.instance_id = Thing.new_id()
self.instance_creator = person
self.instance_creator.addThing(self)
Upvotes: 1