Search code examples
pythoninheritancedel

How to inherit __del__ function


I am reading the Python Essential Reference 4th ed. and I cannot figure out how to fix a problem in the following code

class Account(object):
    num_accounts = 0

    def __init__(self, name, balance):
        self.name = name
        self.balance = balance
        Account.num_accounts += 1

    def __del__(self):
        Account.num_accounts -= 1

    def deposit(self, amt):
        self.balance += amt

    def withdraw(self, amt):
        self.balance -= amt

    def inquire(self):
        return self.balance

class EvilAccount(Account):    
    def inquire(self):
        if random.randint(0,4) == 1:
            return self.balance * 1.1
        else:
            return self.balance

ea = EvilAccount('Joe',400)

If I understand correctly, the ea object goes out of scope when the program ends and the inherited __del__ function should be called, correct? I receive a 'NoneType' object has no attribute num_accounts in __del__. Why doesn't it complain earlier then in the __init__ function?


Solution

  • From the docs:

    Warning: Due to the precarious circumstances under which __del__() methods are invoked, exceptions that occur during their execution are ignored, and a warning is printed to sys.stderr instead. Also, when __del__() is invoked in response to a module being deleted (e.g., when execution of the program is done), other globals referenced by the __del__() method may already have been deleted or in the process of being torn down (e.g. the import machinery shutting down). For this reason, __del__() methods should do the absolute minimum needed to maintain external invariants. Starting with version 1.5, Python guarantees that globals whose name begins with a single underscore are deleted from their module before other globals are deleted; if no other references to such globals exist, this may help in assuring that imported modules are still available at the time when the __del__() method is called.