__getattr__()
class A:
def __getattr__(self,name):
print(f"getting {
name}")
raise AttributeError
o = A()
print(o.test)
The program calls the property of an object, what do you want the program to do when the property does not exist, here we print the desired property and throw an exception
__getattribute__()
class A:
def __init__(self):
self.exist = True
def __getattribute__(self, item):
print(f"getting {
item}")
return None
o = A()
print(o.exist)
print(o.test)
This method will be called whenever you try to read a property of an object. The demo above shows that it will be called regardless of whether the property being read exists or not.
class A:
def __init__(self):
self.exist = True
self.counter = 0
def __getattribute__(self, item):
if item == 'exist':
self.counter += 1
return super().__getattribute__(item)
o = A()
print(o.exist)
print(o.counter)
Here we cannot directly call the method during the return value of the magic method __getattribute__()
, otherwise it will recurse infinitely. Need to addsuper
__setattr__()
Adding or modifying properties will trigger his execution
class A:
def __init__(self):
self.exist = True
self.counter = 0
def __setattr__(self, key, value):
print(f"key is {
key} value is {
value}")
super().__setattr__(key, value)
o = A()
o.exist = False
print(o.exist)
__delattr__()
During the normal generation and death of an object, this function will not be called. This function will be called when we try to delete the properties of an object.
class A:
def __init__(self):
self.exist = True
self.counter = 0
def __delattr__(self, item):
print(f"del {
item}")
super().__delattr__(item)
o = A()
del o.exist
__dir__()
dir
The method is used to return all available attributes or methods. Python stipulates that this method must return one sequence
. The most common one sequence
is a list. Here we return a list
class A:
def __init__(self):
self.exist = True
self.counter = 0
def __dir__(self):
lst = super().__dir__()
return [el for el in lst if not el.startswith("_")]
o = A()
print(dir(o))
__slots__
This is not a method, but an attribute, which specifies which customizations can exist in this class attribute
, and is a whitelist mechanism
__init_subclass__()
This method should be defined in the base class. When we use this class as the base class to create a derived class, this method will be called
class Base:
def __init_subclass__(cls, **kwargs):
print(cls)
class A(Base):
pass
o = A()
__set_name__()
class D:
def __set_name__(self, owner, name):
print(owner,name)
class A:
x = D()
o = A()
When we build an instance of this class in another class, this method will be called. In fact, we still define the descriptor