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?
__del__ is a destructor method which is called as soon as all references of the object are deleted i.e when an object is garbage collected. Syntax: def __del__(self): body of destructor . . Example: Here is the simple example of destructor.
Solution for AttributeError Errors and exceptions in Python can be handled using exception handling i.e. by using try and except in Python. Example: Consider the above class example, we want to do something else rather than printing the traceback Whenever an AttributeError is raised.
Python hasattr() FunctionThe hasattr() function returns True if the specified object has the specified attribute, otherwise False .
Python's magic method __setattr__() implements the built-in setattr() function that takes an object and an attribute name as arguments and removes the attribute from the object. We call this a “Dunder Method” for “Double Underscore Method” (also called “magic method”).
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 tosys.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 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; see PEP 442.
When __del__()
method called, the Groupclass may be recovered by the garbage collection mechanism, so using Groupclass.xxx may failed. But you can access the count variable through self.__class__.count
. Code likes below:
def __del__(self):
self.__class__.count -= 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With