Why doesn't my finaliser run here?

Chris Angelico rosuav at gmail.com
Sun Sep 4 09:01:10 EDT 2016


On Sun, Sep 4, 2016 at 10:37 PM, Ben Finney <ben+python at benfinney.id.au> wrote:
>> And an example:
>>
>>
>> py> e = Eggs()
>> instance created successfully
>> self definitely exists: <__main__.Eggs object at 0xb7bf21ec>
>> Traceback (most recent call last):
>>   File "<stdin>", line 1, in <module>
>>   File "<stdin>", line 8, in __init__
>> Exception
>> py>
>
>
> Right. The instance is constructed successfully (by ‘__new__’, the
> constructor). It will be bound to ‘s’, creating a reference to the
> instance.
>
> The exception raised from the initialiser does not stop you from binding
> the instance to a name. That binding succeeds; the reference remains.
> Nothing has caused that reference to go away.

Presumably you mean "bound to 'e'" here. But it isn't; the expression
Eggs() raised an exception, so nothing got assigned anywhere. It
doesn't depend on __new__ either:

>>> class Eggs:
...  def __init__(self):
...   print("init:", self)
...   raise Exception
...  def __del__(self):
...   print("del:", self)
...
>>> e=Eggs()
init: <__main__.Eggs object at 0x7ffa8fc97400>
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __init__
Exception
>>> e
del: <__main__.Eggs object at 0x7ffa8fc97400>
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'e' is not defined

There's a reference here somewhere, though. My suspicion is it's in
sys.exc_info / sys.last_traceback, which is why triggering another
exception causes the object to be cleaned up.

ChrisA



More information about the Python-list mailing list