def __init__(self):

Steven D'Aprano steve at pearwood.info
Tue Apr 26 12:12:16 EDT 2016


On Tue, 26 Apr 2016 06:25 pm, Marko Rauhamaa wrote:

> Ben Finney <ben+python at benfinney.id.au>:
> 
>> Gary Herron <gherron at digipen.edu> writes:
>>
>>>    The __init__ method is the constructor for instances of a class.
>>>    It is not required, but the situations in which a constructor is
>>>    not needed are few and unusual.
>>
>> That's needlessly confusing: ‘__init__’ is not a constructor because
>> it does not construct the instance. The ‘__new__’ method is the
>> constructor for a class (and returns the new instance).
> 
> I have never ever had a temptation to specify a __new__ method. I can't
> imagine a *beneficial* case of overriding it.

I'm afraid that's a failure of your imagination then.

The obvious reason for overriding __new__ is to construct an immutable
instance. You have to override __new__, because by the time it returns the
instance is immutable and you can no longer initialise it.


>> The ‘__init__’ method requests the already-constructed instance to
>> initialise itself (and returns None).
> 
> It is a serious practical problem that an object can't guarantee that
> its __init__ has been called.

No object can guarantee that any method is called. Python doesn't make an
exception for __new__ or __init__. I'm not sure why you would want it to.


> Check out some of the stdlib source code for example:
> 
> ========================================================================
> class ThreadPoolExecutor(_base.Executor):
>     def __init__(self, max_workers):
>         """Initializes a new ThreadPoolExecutor instance.
> 
>         Args:
>             max_workers: The maximum number of threads that can be used to
>                 execute the given calls.
>         """
>         self._max_workers = max_workers
>         self._work_queue = queue.Queue()
>         self._threads = set()
>         self._shutdown = False
>         self._shutdown_lock = threading.Lock()
> ========================================================================
> 
> Notice how _base.Executor.__init__(self) does not get called. 

What makes you think it needs to be called?


> It can only work if _base.Executor does not specify an __init__. 

That's not the only way. For example, if the __init__ doesn't nothing, just
like object.__init__. You can actually pass anything you like to
object.__init__, and nothing happens:

object.__init__([])




-- 
Steven




More information about the Python-list mailing list