Magic method is a special method that can add magic to your class , If your object implements ( heavy load ) One of these methods , Then this method will be Python The call , You can define what you want to do , And all this is automatically triggered . They are often named after two underscores ( such as __init__
,__lt__
),Python The magic method is very powerful , So it is very important to know how to use it !
__init__(self[, ...])
,__new__(cls[, ...])
,__del__(self)
1)__init__
Constructors , The initialization method when an instance is created . But it's not the first method to instantiate calls ,__new__
That's the first method that instantiates an object , It only takes off cls Parameters , And pass other parameters to __init__
. __new__
Rarely used , But there are also suitable scenes , Especially when a class inherits from a type that doesn't change very often, such as a tuple or string .
2)__new__
Pay attention to the following four points when using :
__new__
Is the first method called when an object is instantiated ;__new__
The first parameter is this class , Other parameters are used to pass directly to __init__
Method ;__new__
Return an instance of the build ;__new__
Decide whether to use the __init__
Method , because __new__
You can call the constructor of other classes or directly return other instance objects as instances of this class , If __new__
No instance object returned , be __init__
Will not be called ;__new__
It is mainly used to inherit an immutable type such as a tuple perhaps string.__new__
Implement singleton mode ( No matter how many instantiations , The result is the same instance )
The singleton pattern (Singleton Pattern) Is a common software design pattern , The main purpose of this pattern is to ensure that only one instance of a class exists . When you want to be in the whole system , When only one instance of a class can appear , A single object can be used .
such as , The configuration information of a server program is stored in a file , Client through a AppConfig Class to read configuration file information . If during the program run , There are a lot of places where you need to use the content of a profile , in other words , Many places need to create AppConfig Instance of object , This results in multiple AppConfig Instance object of , And this is a serious waste of memory resources , Especially when the configuration file has a lot of content . in fact , similar AppConfig Such a class , We want to have only one instance object during program execution .
give an example :
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __new__(cls, *args, **kwargs):
if not hasattr(cls,'instance'): # Optimize , If the instance does not exist, the parent class instance is returned
cls.instance = super().__new__(cls)
return cls.instance # The point is here ! Directly return to the current instance
a = Person('p1',21)
b = Person('p2',22)
print(a == b, a.name == b.name) # The print results here are True, so a and b It's all the same ( example b Covers the instance a).
# Single case effect :
# First of all 、 Control the use of resources , Control the concurrent access of resources through thread synchronization ;
# second 、 Control the number of instances generated , To save resources ;
# Third 、 To use as a medium of communication , That is data sharing . such as , The design of database connection pool generally adopts singleton mode , A database connection is a database resource .
# Application scenarios :
#Python Of logger It's a singleton pattern , For logging
# Thread pool 、 Resource pools such as database connection pool generally use singleton mode
#Windows The resource manager for is a singleton pattern
# Website counter
3)__del__
Destructor , Called when the instance is destroyed .
__call__(self[,args ...])
,__getitem__(self,key)
,__setitem__(self,key,value)
1)__call__()
: Allow an instance of a class itself to be called like a function , as follows .
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
self.instance = add # Instance object plus (), Will call add() function
def __call__(self,*args):
return self.instance(*args)
def add(args):
return args[0] + args[1]
a = Person('p1', 20)
print(a([1,2]))
# This will print 3
# Visible when creating a After this object , If you define __call__ Function, the object can be called like a function .
2)__getitem__()
: Defines the behavior of getting the specified elements in the container , Equivalent to a dictionary "[ ]" operation , Such as self[key].
Examples are as follows .
''' No one answers the problems encountered in learning ? Xiaobian created a Python Exchange of learning QQ Group :857662006 Looking for small partners who share the same aspiration , Help each other , There are also good video tutorials and PDF e-book ! '''
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
self._registry = {
'name': name,
'age': age
}
def __call__(self, *args):
return self.instance(*args)
def __getitem__(self, key):
if key not in self._registry.keys():
raise Exception('Please registry the key:%s first !' % (key,))
return self._registry[key]
a = Person('p1', 20)
print(a['name'],a['age'])
# It's printed here 'p1' 20
# so __getitem__ Make the instance accessible like a dictionary
3)__setitem__()
: Set the behavior of the specified element in the container , Equivalent to a dictionary "[ ]" operation , Such as self[key] = value .
__getattr__(self,name)
,__getattribute__(self,name)
,__setattr__(self,name,value)
,__delattr__(self,name)
use point "." Trigger during operation .
1)__getattr__ ()
: Triggered when the user attempts to access a nonexistent property ;
2)__getattribute__()
: When an attribute ( Whether it exists or not ) Triggered when accessed ;
3)__setattr__ ()
: Triggered when a property is set ;
4)__delattr__ ()
: Triggered when an attribute is deleted .
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
self._registry = {
'name': name,
'age': age
}
def __getattribute__(self, item):
# Be careful not to access properties here , Such as self.__dict__[item]
# because self.__dict__ Still will be __getattribute__ Intercept , This will fall into a dead circle
return object.__getattribute__(self,item)
def __getattr__(self, item):
print("don't have the attribute ",item)
return False
def __setattr__(self, key, value):
self.__dict__[key] = value
a = Person('p1', 20)
print(a.cs) # It will print don't have the attribute cs as well as False
a.cs = ' test ' # Here, set the attribute value to ' test '
print(a.cs) # Here will print out ' test '