Python attributeError on __del__
Question: I have a python class object and I want to assign the value of one class
variable

    
    
    class Groupclass(Workerclass):
        """worker class"""
        count = 0
    
        def __init__(self):
            """initialize time"""
            Groupclass.count += 1
            self.membercount = 0;
            self.members = []
    
        def __del__(self):
            """delte a worker data"""
            Groupclass.count -= 1
    
    
    if __name__ == "__main__":
        group1 = Groupclass()
    

This execution result is correct, but there's an error message that says:

    
    
    Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound method Groupclass.__del__ of <__main__.Groupclass instance at 0x00BA6710>> ignored
    

Can someone tell me what me I did wrong?


Answer: Your `__del__` method assumes that the class is still present by the time it
is called.

This assumption is incorrect. `Groupclass` has already been cleared when your
Python program exits and is now set to `None`.

Test if the global reference to the class still exists first:

    
    
    def __del__(self):
        if Groupclass:
            Groupclass.count -= 1
    

or use `type()` to get the local reference:

    
    
    def __del__(self):
        type(self).count -= 1
    

but do note that this means that the semantics for `count` change if
`Groupclass` is subclassed (each subclass gets a `.count` attribute versus
only `Groupclass` having a `.count` attribute).

Quoting from the `__del__` hook documentation:

> **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.

If you are using Python 3, two additional notes apply:

  * CPython 3.3 automatically applies a [randomized hash salt](https://docs.python.org/3/reference/datamodel.html#object.__hash__) to the `str` keys used in a `globals` dictionary; this also affects the order in which globals are cleaned up, and it _could_ be that you see the problem on only _some_ of the runs.

  * CPython 3.4 no longer sets globals to `None` (in most cases), as per [Safe Object Finalization](https://docs.python.org/3/whatsnew/3.4.html#whatsnew-pep-442); see [PEP 442](http://www.python.org/dev/peps/pep-0442/).

