I have the following class, which acts as a collection of people:
class Person:
PERSONS = dict() # name ==> instance
def __new__(cls, *args, **kwargs):
name = kwargs.get('name') or '' if not args else args[0]
print ('Name: %s' % name)
if name in cls.PERSONS:
print ('Returning found person!')
return cls.PERSONS[name]
else:
print ('Initializing new person')
return super(Person, cls).__new__(cls)
def __init__(self, name):
print ("Running init")
self.name = name
Person.PERSONS[name] = self
If a person is found, it returns that person, otherwise it creates a new one. And when I run it it works:
>>> p1 = Person('Julia')
Name: Julia
Initializing new person
Running init
>>> p2 = Person('Julia')
Name: Julia
Returning found person!
Running init # <== how to get this not to run?
>>> p1 is p2
True
However, if the person is found, I don't want the __init__
method to run. How would I "skip" the init method based on the return of the __new__
?
One option is to add a conditional in the __init__
, such as:
def __init__(self, name):
if name in Person.PERSONS: return # don't double-initialize
print ("Running init")
self.name = name
Person.PERSONS[name] = self
But I was hoping there might be a cleaner approach.