[Tutor] __new__ and __init__

Hugo Arts hugo.yoshi at gmail.com
Wed Aug 1 17:10:06 CEST 2012


On Wed, Aug 1, 2012 at 4:28 PM, rail shafigulin
<rail.shafigulin at gmail.com>wrote:

> Hello everyone.
>
> I'm trying to understand how to use the two methods. I know that __new__
> is used to create an object, while __init__ to initialize. But I'm not sure
> what happens when I create an object.
>
> I found the following code in the book (Python 3 Object Oriented
> Programming by Dusty Phillips)
>
> import weakref
>
> class CarModel:
>   _models = weakref.WeakValueDictionary()
>
>   def __new__(cls, model_name, *args, **kwargs):
>     model = cls._models.get(model_name)
>     if not model:
>       model = super().__new__(cls)
>       cls._models[model_name] = model
>     return model
>
>   def __init__(self, model_name, air = False, tilt = False, cruise_control
> = False, power_locks = False, alloy_wheels = False, usb_charger = False):
>     if not hasattr(self, "initted"):
>       self.model_name = model_name
>       self.air = air
>       self.tilt = tilt
>       self.cruise_control = cruise_control
>       self.power_locks = power_locks
>       self.alloy_wheels = alloy_wheels
>       self.usb_charger = usb_charger
>       self.intted = True
>
>
> dx = CarModel("Fit DX")
> lx = CarModel("Fit LX", air = True, tilt = True, cruise_control = True,
> power_locks = True, alloy_wheels = True, usb_charger = True)
>
> I assume when I call CarModel(<parameters>) __new__is being called first
> and then __init__ after it.
> 1) Does it mean that __new__ and __init__ must have the same parameters?
> In this particular case __new__ and __init__ both have model_name and if I
> understand correctly when __new__ is called the rest of the parameters
> (air, tilt, cruise_control, etc) are absorbed by the *args argument. Please
> correct me if I am wrong.
>

This is exactly right.


> 2) What happens if I don't use the same parameters, say in the case of
> __init__ I will remove model_name, will I still be able to call dx =
> CarModel("Fix DX")
>
>
Why didn't you try it yourself? It's only a few modifications. If you
remove all references to model_name in __init__, the first CarModel call
will still seem to work, but with a little poking you'll realize that it
really doesn't. The string "Fix DX" is assigned to model_name in __new__,
and since __init__ is called with the exact same arguments always* "Fix DX"
will simply end up assigned to the air argument of __init__, and that
really isn't what you want in almost every situation.

* small caveat: I'm entirely unsure of this, but I *think* if you create
CarModel with a metaclass that overrides __call__ you can change the way
__new__ and __init__ work? If anyone can confirm this, be my guest.

HTH,
Hugo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20120801/560a2a9b/attachment.html>


More information about the Tutor mailing list