Static Method and Class Method
1. Static method
- Decorate with the decorator @static method. Static methods need neither pass class objects nor instance objects
- Static methods can also be accessed through instance objects and class objects
class Dog: type = 'Dog' def __init__(self): name = None #Static method @staticmethod def introduce():#Static methods do not automatically pass instance objects and class objects print('Canidae mammals belonging to the order Carnivora') dog = Dog() Dog.introduce() dog.introduce()
Canidae mammals belonging to the order Carnivora
Canidae mammals belonging to the order Carnivora
Static methods are functions in classes and do not require instances.
Static methods are mainly used to store logical code. Logically, they belong to classes, but they have nothing to do with classes themselves. That is to say, they do not involve attributes and method operations in classes.
Understandably, static methods are independent, simple functions that are managed only in the namespace of a class for easy maintenance and management.
Class method
- Methods owned by class objects
- The decorator @classmethod is needed to identify it as a class method.
- For class methods, the first parameter must be a class object, usually cls as the first parameter
class Dog: __type = 'Dog' #Class method, decorated with class @classmethod def get_type(cls): return cls.__type print(Dog.get_type())
Use scenarios:
- Class methods are defined when class objects (such as access to private class attributes, etc.) need to be used in methods.
- Class methods are generally used in conjunction with class attributes.
Be careful:
When an object method with the same name, a class method, and a static method are defined in a class, the calling method takes precedence over the last defined method.
class Dog: def demo_mtehod(self): print('Object method.') @classmethod def demo_method(cls): print('Class methods.') @staticmethod def demo_method(): #Finally, it is defined. Priority of execution on invocation print('Static method.') dog = Dog() Dog.demo_method() dog.demo_method()
Static method.
Static method.
property
In Python, it mainly provides a convenient way to manipulate attributes.
If we need to design a bank account class now, it includes the name of the account holder and the balance. (If we don't consider the specific operation interface now.)
Simple implementation
class Account(object): def __init__(self,name,money): self.name = name self.money = money
Questions:
Insecurity (design is simple and convenient, all attributes can be accessed and modified externally, very insecure)
Improvement 1
Hide implementation details
For account information, the amount is not allowed to be modified directly by the user. If you change it, you can only go to the window.
How to implement the program?
When using objects, try not to let users directly manipulate the attributes in the objects, because direct manipulation will bring security risks.
At this point, consider private attributes
class Account(object): def __init__(self,name,money): self.name = name self.money = money
After code improvement, all attributes are designed as private attributes. When they are used externally, they do not know the internal attributes, can not modify the object directly, and hide the details of implementation.
But there is a new problem. What if you really need to modify these two attributes?
Improvement 2 provides an accurate access
class Account(object): def __init__(self,name,money): self.name = name self.__balance = money def get_name(self): return self.name def set_balance(self,money): self.__balance = money def get_balance(self): return self.__balance
After modification, when using the object of this class externally, if you want to use the attributes in the object, you can only operate through the set/get interface provided in the class, which improves the security of the program.
In this way, the program basically meets the design requirements, but can it be more perfect?
If in the process of using the object of this class, due to misoperation, abnormal data is introduced, resulting in abnormal data. How can this be avoided?
For example, negative numbers, strings, or other types of objects appear when setting the amount.
Improvement 3 Guarantees Data Validity
In the set_balance method, the incoming data is judged effectively, and if it is invalid, the user is prompted to have problems.
class Account(object): def __init__(self,name,money): self.name = name self.__balance = money def get_name(self): return self.name def set_balance(self,money): if isinstance(money,int): if money > 0: self.__balance = money else: raise ValueError('Input amount incorrect') else: raise ValueError('Input amount is not a number') self.__balance = money def get_balance(self): return self.__balance
After several versions of iteration, the program looks more robust and more secure.
But in the use process, it can be more refined.
Attribute operation
In the property class, a property class is provided. By setting up the object to create this class, when using the private property of the object, we can no longer use the method of calling the function of the property, but use the property just like the common property, so as to provide convenience for the developer.
property(fget = None,fset = None,fdel = None,doc = None)#property attribute
property is a class. The _init_ method consists of four parameters. After the instance, it returns an object to manipulate the properties.
- Parametric 1: Attribute acquisition method
- PARAMETER 2: THE SETTING METHOD OF ATTRIBUTES
- Parametric 3: Method of deleting attributes
- Parametric 4: Attribute description
(In order, or you will make a mistake)
class Account(object): def __init__(self,name,money): self.__name = name self.__balance = money def __get_name(self): return self.__name def set_balance(self,money): if isinstance(money,int): if money > 0: self.__balance = money else: raise ValueError('Input amount incorrect') else: raise ValueError('Input amount is not a number') def get_balance(self): return self.__balance #Use the property class to set traversal access to properties name = property (__get_name) balance = property(get_balance,set_balance) ac = Account('Tom',10000) print(ac.name) print(ac.balance) ac.balance = 1000 print(ac.balance)
Tom
10000
1000
class Account(object): def __init__(self, name, money): self.__name = name self.__balance = money @property def name(self): return self.__name @property def balance(self): return self.__balance @balance.setter def balance(self, money): if isinstance(money, int): if money > 0: self.__balance = money else: raise ValueError('Input amount incorrect') else: raise ValueError('Input amount is not a number') ac = Account('Tom', 10000) print(ac.name) print(ac.balance) ac.balance = 1000 print(ac.balance)
After using the property class instance object, when using the attributes in the object, it can be invoked as if using common public attributes, but the set/get method is actually invoked. In the case of an instance property object, not all parameters need to be written, for example, the name in the example provides only the get method and is a private method. This completely hides the internal implementation details.
self
What if the properties of an object need to be used in its methods?
- Keyword self is mainly used in object method to represent the object calling the method.
- Using self in the method, we can get the object that calls the current method, and then get the attributes and methods of the object.
When calling the method of an object, why don't you need to set the parameters corresponding to self?
- When an object calls its method, the Python interpreter passes the object to the method as the first parameter, so the developer only needs to reserve the first parameter self when redefining it.
class Cat: #Method def introduce(self): print('name is %s,age is : %d'%(self.name,self.age)) #Instantiate, create an object cat = Cat() cat.name = 'aa' cat.age = 8 cat.introduce()
name is aa,age is : 8
Define attributes within methods
- Using self to manipulate attributes and variable names of objects is similar in effect.
class Cat: def introuce(self): self.type = 'Small animals' cat = Cat() cat.introuce() print(cat.type)
_ new_ Method
- When an object is created, the system automatically calls the _new_ method.
- Developers can use the _new_ method to customize the object creation process.
-_ new_ must have at least one parameter cls representing the class to be instantiated, which is automatically provided by the Python interpreter when instantiated
-_ New_ must have a return value to return the instance instantiated. This is especially important when you implement _ new_ yourself. You can return instances from the parent class _ new_ or directly from the object __________ instance.
-_ init_ has a parameter self, which is the instance returned by _new_. On the basis of _new_, init_ can complete some other initialization actions, and _init_ does not need a return value.
- If a custom parameter is passed when an object is created and the new method is rewritten, the new method must also "reserve" the parameter, otherwise the _init_ method will not be able to obtain the parameter.
class A(object): def __new__(cls, x): print ('this is in A.__new__, and x is ', x) return super(A, cls).__new__(cls) def __init__(self, y): print ('this is in A.__init__, and y is ', y) class C(object): def __new__(cls, n): print ('this is in C.__new__, and n is ', n) return super(C, cls).__new__(cls) def __init__(self, a): print ('this is in C.__init__, and a is ', a) class B(A): def __new__(cls, z): print ('this is in B.__new__, and z is ', z) return A.__new__(cls, z) def __init__(self, m): print ('this is in B.__init__, and m is ', m) # class B(A): # def __new__(cls, z): # print 'this is in B.__new__, and z is ', z # return object.__new__(cls) # def __init__(self, m): # print 'this is ni B.__init__, and m is ', m if __name__ == '__main__': a = A(100) print ('=' * 20) b = B(200) print (type(b))
this is in A.new, and x is 100
this is in A.init, and y is 100====================
this is in B.new, and z is 200
this is in A.new, and x is 200
this is in B.init, and m is 200
<class 'main.B'>
_ call__method
Objects are parenthesed to trigger execution
The execution of the constructor is triggered by the creation of an object, that is, object = class name ()
For example, the execution of the _call_ method is triggered by the parentheses of the object, that is, the object () or the class ().
class A(object): def __call__(self,x): print('call',x) a = A() a('123')
_ doc_ method
This property cannot be inherited to subclasses
class Foo: """This is a note.""" pass class Bar(Foo): pass print(Foo.__doc__) print(Bar.__doc__)
This is a note.
None