As an object-oriented (Object) Programming language ,Python Of course, the core of contains classes (class) The design of the . This article introduces the methods of classes in detail , The details are as shown in the figure below :
Class variables will Share among all class instances , When the class instance has not been created , Class variables already exist . Class variables are defined outside of all methods , Usually just below the class header and before constructors and other methods .
class People():
class_name = "demo" # Class variables
def __init__(self):
pass
if __name__ == "__main__":
print(People.class_name)
# demo
print(People().class_name)
# demo
Class variables can be directly referenced by class names , You can also refer to... Through class instances .
Class instance variables Owned by class instances , Each class instance has its own set of independent class instance variables .
class People():
class_name = "demo" # Class variables
def __init__(self, name="", age=1, sex="M") -> None:
self.name = name # Class instance variables
self.age = age
self.sex = sex
if __name__ == "__main__":
p = People(name="Tom")
p1 = People(name="Tony")
print(p.name, p1.name)
# Tom Tony
Example method (instance methods) For the data provided by the instance variable / Value performs a series of operations . The first parameter of the instance method must be self
, It refers to the current object , Used to access variables and methods in a class . Example method Not shared between classes . In the following example code ,__init__
and print_info
Are instance methods of classes .
class People():
def __init__(self, name="", age=1, sex="M") -> None:
self.name = name
self.age = age
self.sex = sex
def print_info(self):
print(f"Name: {
self.name}, Age: {
self.age}, Sex: {
self.sex}")
if __name__ == "__main__":
p = People("Tom", 22, "M")
p.print_info()
Here we focus on the class initialization method __init__()
, The method This method will be called automatically when the class instance is created .
In the constructor of a class , If exist Inherit Relationship , Can pass super()
Method to call the initialization method of the parent class to complete the initialization of the parent class property .
super()
Method can return a temporary object of a superclass , It can then be used to call methods of the superclass .super()
Method can contain two parameters :
class Rectangle:
def __init__(self, length, width):
self.length = length
self.width = width
def area(self):
return self.length * self.width
def perimeter(self):
return 2 * self.length + 2 * self.width
class Square(Rectangle):
def __init__(self, length):
super(Square, self).__init__(length, length)
Python3 in
super(Square, self)
The call to is equivalent to no parametersuper()
Call to .
__call__
Method Python allow class Define special instance methods __call__
, Through this method, we can make Call an object like a function .
from collections import defaultdict
class CountMissing():
def __init__(self):
self.add = 0
def __call__(self):
self.add += 1
return 0
if __name__ == "__main__":
items = {
'apple': 3, 'banana': 2}
goods = [('orange', 6), ('watermelon', 1), ('strawberry', 9), ('apple', 8)]
# Statistics goods stay items Nonexistent fruit categories
counter = CountMissing()
items = defaultdict(counter, items)
for fruit, num in goods:
items[fruit] += num
print(counter.add)
# 3
Same kind of variables , Class method (class methods) yes Methods shared by all class examples . Class methods can only access class variables , You cannot access class instance variables ( Because the class instance has not been created ). Class methods can Modify the state of the class by modifying the class variables .
@classmethod
Decorator stay Python in , have access to @classmethod
Decorator to declare a method as a class method .
class People():
class_name = "demo" # Class properties
def __init__(self, name="", age=1, sex="M"):
self.name = name # Instance attributes
self.age = age
self.sex = sex
@classmethod
def print_info(cls):
print(f"class name: {
cls.class_name}")
if __name__ == "__main__":
People.print_info()
# class name: demo
People().print_info()
# class name: demo
Considerations for class methods include :
cls
;class_name
, But you cannot access instance properties , for example self.name
; Class name . Method name
To call , It can also be done through Class instance object . Method name
To call .Use
@classmethod
The benefits of : When you refactor the class later , There is no need to modify the initialization function , Just add an extra function to handle , And then use@classmethod
that will do .
classmethod()
Method Python You can also use the built-in classmethod(function)
Method to convert the methods of normal methods into class methods , among function
Is the name of the function to be converted to a class method .
class People():
class_name = "demo" # Class properties
def __init__(self, name="", age=1, sex="M"):
self.name = name # Instance attributes
self.age = age
self.sex = sex
def print_info(cls):
print(f"class name: {
cls.class_name}")
if __name__ == "__main__":
People.print_info = classmethod(People.print_info)
People().print_info()
# class name: demo
Static methods (static methods) Similar to class methods , It is also bound to the class , Not on class instance objects . But static methods are not like self
and cls
Such an implicit first parameter , That means it Cannot access class variables and class instance variables . Static methods can also pass Class name . Static method name
The way to call .
Similar to class methods , Static methods can be passed through @staticmethod
Decorator or built-in staticmethod(function)
Method to define .
class People():
class_name = "demo" # Class properties
def __init__(self, name="", age=1, sex="M"):
self.name = name # Instance attributes
self.age = age
self.sex = sex
@staticmethod
def temp(x):
print(x)
def temp1(x, y):
print(x + y)
if __name__ == "__main__":
People.temp1 = staticmethod(People.temp1)
People.temp(10) # 10
People.temp1(10, 20) # 30
@property Decorator
Python Provides @property
Decorator , It makes it possible to use getter
and setter
Make it easy . In general , As long as the class attribute is not set as a private attribute, you can freely use the class attribute outside the class . But sometimes , You may want to do some special behavior when setting properties , For example, check whether the set value is greater than 0. In this case ,@property
The decorator will come in handy , for example :
class Circle():
def __init__(self, radius):
self.radius = radius
@property
def radius(self):
return self.radius
@radius.setter
def radius(self, radius):
if radius <= 0:
raise ValueError(f"Circle's radius must be > 0, but get {
radius}")
self.radius = radius
c = Circle(-2)
# ValueError: Circle's radius must be > 0, but get -2
In this example , Class initializes the incoming parameters radius=-2
, In the class initialization function, when self.radius = radius
Will automatically call @radius.setter
Method , Its inspection raduis
Is less than or equal to 0, Trigger exception .
Python Classes of also have similar Java and C++ Access control for , It can also be divided into Public、Protected and Private.
.
Access directly ;_
, It can only be accessed through class methods and subclasses themselves . Be careful , this It is not mandatory , I just hope that users will follow such requirements .__
start , Can only be accessed through class methods .class People():
def __init__(self, name, age, id):
self.name = name # public
self._age = age # protected
self.__id = id # private
def _protected_mthd(self):
print("Protected")
def __private_mthd(self):
print("Private")
if __name__ == "__main__":
p = People("Tom", 22, "1001")
print(p._age) # Although defined as containing type , But you can still access it directly , It's just Python This is not recommended
# 22
p._protected_mthd()
# Protected
print(p.__id)
# AttributeError: 'People' object has no attribute '__id'
p.__private_mthd()
# AttributeError: 'People' object has no attribute '__private_mthd'
actually ,Python Middle Union There is no protection mechanism that prevents access to a member of a class . In the outside world, the reason why private properties cannot be accessed is not because of the protection mechanism , Instead, class methods use Name translation mechanism , That is, for private properties __X
, It will be transcribed as _classname__X
, among classname
For class name ( Private methods are similar ).
print(p._People__id)
# 1001
p._People__private_mthd()
# Private
Through the above name translation mechanism , Sure Avoid naming conflicts during class inheritance ( A subclass defines an attribute with the same name as the parent class ).