Decorator
Closure decorator
The essence of decorator is a closure. There are three elements of closure: 1. Function nesting, 2. External function returns the reference of internal function, and internal function uses the variable of external function
1. Use the decorator to simply realize a login verification function
In [1]: user = {"username": "123", "password": 123} def outter(func): ...: def inner(*args, **kwargs): ...: if user.get('token'): ...: return func(*args, **kwargs) ...: else: ...: username = input("user:") ...: password = input("pwd:") ...: if user.get("username") == username: ...: user['token'] = True ...: print("login success") ...: return func(*args, **kwargs) ...: else: ...: raise ValueError('login faild') ...: return inner ...: In [8]: @outter # func = outer(tests) ...: def tests(a, b): ...: print('tests result:',a*b) ...: In [9]: tests(2,4) # outer(tests)(2, 4) user:123 pwd:123 login success tests result: 8 In [10]: tests(2,4) tests result: 8 In [11]: tests(2,9) tests result: 18
Class
@classmethod
After decorating the magic square of @ classmethod in the class, it belongs to the class method. The first parameter passed is the class object, which can be called directly by the class object, and the class method can also be called by the instance method, but the class method cannot call the instance method
Usage scenario: call when instantiation is not required
class Method: ...: def __init__(self): ...: pass ...: @classmethod # After decorating, the decorator becomes a class method, which can be called directly by the class ...: def trf(cls): ...: print(cls) ...: def test(self): # Example method ...: print(self) ...: self.trf() ...: ...: In [23]: Method.trf() <class '__main__.Method'> In [24]: Method.test() --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-24-23908d4c4445> in <module> ----> 1 Method.test() TypeError: test() missing 1 required positional argument: 'self' In [25]: s = Method() In [26]: s.trf() <class '__main__.Method'> In [27]: s.test() <__main__.Method object at 0x000001ADD8BE3C18> <class '__main__.Method'>
@staticmethod method
The instance method modified by the staticmethod method can pass no parameters, just like the normal magic method
@property method
Setting the property decorator can call an instance just like calling properties through an instance,
Usage scenario: this decoration can be used for attributes that do not want to be modified
Class magic method
Use of new method
In a class, the first way to create an instance object is__ new__ Magic method, the new method allocates memory to the object, so one method used during initialization of each instance is the new method
Usage scenario: this magic method is often used to set a single instance
In [38]: class bdss: ...: sunclss = None # In non singleton mode, as long as the class attribute is changed, the next instance will use the changed class attribute value ...: def __new__(cls, *args, **kwargs): ...: print(cls.sunclss) ...: from random import randint ...: cls.sunclss = randint(1, 40) ...: print('-------',cls.sunclss) ...: return super().__new__(cls, *args, **kwargs) In [39]: a = bdss() None ------- 2 In [40]: b = bdss() 2 ------- 33 In [41]: c = bdss() 33 ------- 37 # Singleton implementation In [28]: class bdss: ...: sunclss = None ...: def __new__(cls, *args, **kwargs): ...: if cls.sunclss: ...: return cls.sunclss ...: else: ...: cls.sunclss = super().__new__(cls, *args, **kwargs) ...: return cls.sunclss ...: ...: In [29]: a = bdss() In [30]: a Out[30]: <__main__.bdss at 0x1add90c69b0> In [31]: b = bdss() In [32]: b Out[32]: <__main__.bdss at 0x1add90c69b0>
__ call__ Use of magic methods
Class__ call__ The magic method can be called like a function to get the result
In [50]: class A: ...: def __init__(self): ...: pass ...: def __call__(self): ...: print('call method') ...: In [51]: In [51]: a = A() In [52]: a() # Instance properties are called like functions call method
Use the class decorator to complete the singleton mode
1 the essence of calling decorator is that external function refers to internal function method,
Therefore, to implement the decorator with a class, it is necessary to trigger a class method when calling a class method__ call__ Method is called when calling a function, so the call method must be used when using class method as decorator
Class (getattr, setattr, delattr)
__ getattr__ And getattribute methods
1 getattribute is called when the class gets the attribute. If the attribute is not found in the class method, the getattr method will be triggered. The getattr method of the parent class will throw no exceptions. Therefore, if you want to not throw exceptions, you can rewrite the getattr method so that it does not throw exceptions
class A: ...: def __init__(self): ...: self.a = 'a' ...: self.b = 'b' ...: ...: def __getattr__(self, key): ...: print('There is an exception calling when the value is not obtained') ...: object.__getattribute__(self, key) ...: ...: In [10]: x = A() In [11]: x.c There is an exception calling when the value is not obtained --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-11-a693afdd9058> in <module> ----> 1 x.c <ipython-input-9-878ca7145054> in __getattr__(self, key) 6 def __getattr__(self, key): 7 print('There is an exception calling when the value is not obtained') ----> 8 object.__getattribute__(self, key) 9 10 AttributeError: 'A' object has no attribute 'c'
If there are many instances of set python method to be overridden, the attribute of setatt2 can be used in the scene if there are many instances of setattr method to be overridden
n [9]: class A: ...: def __init__(self): ...: self.a = 'a' ...: self.b = 'b' ...: ...: def __setattr__(self, item, value): ...: print('__setattr__') ...: object.__setattr__(self, item, value) ...: ...: ...: ...: def __delattr__(self, item): ...: print('Property deleted') ...: object.__delattr__(self, item) ...: ...: def __getattr__(self, key): ...: print('There is an exception calling when the value is not obtained') ...: object.__geta ...: ttribute__(self, key) ...: In [10]: xi = A() __setattr__ __setattr__ In [11]: del xi.a Property deleted