Python Basics (classes and objects)
1, Two ideas of programming
Process oriented and object-oriented
Process oriented | object-oriented | |
---|---|---|
difference | Things are relatively simple and can be solved by linear thinking | Things are complicated and cannot be solved by simple linear thinking |
Common ground: both object-oriented and process oriented are a way of thinking to solve practical problems
The two complement each other and are not opposite. To solve complex problems, the object-oriented method is convenient for us to grasp the complex relationship between things from a macro perspective and analyze the whole system; When it comes to micro operations, the process oriented approach is still used
2, Class
Category, classification, birds of a feather flock together, humans, birds, animals, plants
- Class is the general name of a group composed of several similar things. It can help us quickly understand and judge the nature of things
3, Define classes in Python
Syntax for creating classes
class Student: #Student is the name of the class (class name), which is composed of one or more words. The first letter of each dandy is uppercase and the rest is lowercase
pass
class Student: #Student is the name of the class (class name), which is composed of one or more words. The first letter of each dandy is uppercase and the rest is lowercase pass
class Student: #Student is the name of the class (class name), which is composed of one or more words. The first letter of each dandy is uppercase and the rest is lowercase pass print(id(Student)) print(type(Student)) print(Student)
Output:
1512775104816 <class 'type'> # Indicates class type <class '__main__.Student'>
Composition of classes
- Class properties
- Example method
- Static method
- Class method
class Student: native_pace='Jilin' #Variables written directly in a class are called class attributes def __init__(self,name,age): self.name=name #self.name, called entity attribute, performs an assignment operation to assign the value of the name of the local variable to the entity attribute self.age=age #Example method def eat(self): print('The students are eating...') #Static method @staticmethod def method(): print('I used it staticmethod So I'm a static method') #Class method @classmethod def cm(cls): print('I'm a class method because I use classmethod Modify') #What is defined outside the class is called a function, and what is defined inside the class is called a method def drink(): print('drink water')
4, Object creation
- Object creation is also called class instantiation
- Syntax:
- Instance name = class name
- example:
- stu=Student()
- Meaning: with an instance, you can call the content in the class
#Create object of Student class stu1=Student('Zhang San',20) print(id(stu1)) print(type(stu1)) print(stu1)
Output:
1668138946320 #Converted to hexadecimal is 18464D44F10 <class '__main__.Student'> <__main__.Student object at 0x0000018464D44F10>
View class objects
print(id(Student)) print(type(Student)) print(Student)
Output:
2460596968352 <class 'type'> <class '__main__.Student'>
Compare the differences between the above instance object and class object
5, Use object
Call the methods and properties of the class
#Create object of Student class stu1=Student('Zhang San',20) stu1.eat() #Object name Method name () print(stu1.name) #Call the properties of the instance object print(stu1.age) print('--------') Student.eat(stu1) #This line has the same function as the above call of eat() method. It calls Student's eat() method #Class name Method name (object of class) -- > is actually self at the method definition
Output:
The students are eating... Zhang San 20 -------- The students are eating...
Comparing the different ways of calling the two methods, the functions are the same
6, Class properties_ Class method__ Class static method
Class attribute: variables outside methods in a class are called class attributes and are shared by all objects of the class
Class method: a method decorated with @ classmethod and directly accessed by class name
Static method: a method decorated with @ staticmethod and directly accessed by class name
print(Student.native_place) # access class properties
Student.cm() # call class method
Student.sm() # calls static methods
How class properties are used
#Usage of similar attributes print(Student.native_pace) stu1=Student('Li Si',20) stu2=Student('Wang Wu',22) print(stu1.native_pace) print(stu2.native_pace) #Modify class properties print('-------------------') Student.native_pace='Tianjin' print(stu1.native_pace) print(stu2.native_pace)
Jilin Jilin Jilin ------------------- Tianjin Tianjin
Indicates that class properties are shared
How class methods are used
print('-----Use of class methods------') Student.cm()
Output:
-----Use of class methods------ I'm a class method because I use classmethod Modify
Class method
@classmethod def cm(cls): print('I'm a class method because I use classmethod Modify')
Use of class static methods
print('-----Use of static methods------') Student.method()
Output:
-----Use of static methods------ I used it staticmethod So I'm a static method
Static method
#Static method @staticmethod def method(): print('I used it staticmethod So I'm a static method')
7, Dynamic binding properties and methods
python is a dynamic language. After creating objects, you can dynamically bind properties and methods
''' Dynamic binding properties and methods ''' class Student: def __init__(self,name,age): self.name=name self.age=age def eat(self): print(self.name+'be at table') stu1=Student('lisi',20) stu2=Student('Li Si',30) print(id(stu1)) print(id(stu2))
A Student class can create N instance objects of multiple Student classes, and the attribute values of each entity object are different
Dynamically bind properties for an instance object
stu1.gender='female' print(stu1.gender)
Output: Female
Compared with java, attributes can be added dynamically on objects
Bind method for instance object
Methods outside the class are called functions, which bind functions to objects
''' Dynamic binding properties and methods ''' class Student: def __init__(self,name,age): self.name=name self.age=age def eat(self): print(self.name+'be at table') stu1=Student('lisi',20) stu2=Student('Li Si',30) print(id(stu1)) print(id(stu2)) stu1.gender='female' print(stu1.gender) #Binding method def show(): print('Those defined outside the class are called functions') stu1.show=show stu1.show()
Output:
2243355037648 2243355037552 female Those defined outside the class are called functions
8, Three characteristics of object-oriented
- Encapsulation: improve program security
- Wrap data (properties) and behavior (Methods) into class objects. Call the method outside the class object on the attribute inside the method. In this way, the specific implementation details inside the relational method are not needed, so the complexity is reduced.
- In Python, there is no special modifier for the private of the attribute. If the attribute does not want to be accessed outside the class object, the first two are used_ “.
- Inheritance: improve code reusability
- Polymorphism: improve program scalability and maintainability
9, Encapsulation
class Car: def __init__(self,brand): self.brand=brand def start(self): print('The car has started...') car=Car('bmw') car.start() print(car.brand)
Output:
The car has started... bmw
Thus, encapsulated properties and methods are used outside the class
Private property
class Student: def __init__(self,age): self.set_age(age) def set_age(self,age): if 0<=age<=120: self.__age=age else: self.__age=18 def get_age(self): return self.__age stu1=Student(150) stu2=Student(30) print(stu1.get_age()) print(stu2.get_age())
Private property
class Student: def __init__(self,name,age): self.name=name self.__age=age #Age doesn't want to be used externally, so two are added__ def show(self): print(self.name,self.__age)
When in use:
stu1=Student('Zhang San',21) print(stu1.__age)
report errors:
print(stu1.__age) AttributeError: 'Student' object has no attribute '__age'
stu1=Student('Zhang San',21) # print(stu1.age) stu1.show()
Output:
Zhang San 21
View private properties when hidden
print(dir(stu1))
Output:
['_Student__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'show']
This allows you to see which properties and methods are available
Not found__ Age attribute, but found a '_ Student__age’
print(stu1._Student__age)
Output: 21
It can still be used outside the class, but it's a little troublesome
10, Inherit
Syntax format
Class subclass class name (parent class 1, parent class 2...):
pass
- If a class does not inherit any classes, it inherits object by default
- Python supports multiple inheritance
- When defining a subclass, the constructor of the parent class must be called in its constructor.
Define class:
Subclass calls superclass method ()
class Person(object): def __init__(self,name,age): self.name=name self.age=age def info(self): print(self.name,self.age) class Student(Person): def __init__(self,name,age,stu_no): super().__init__(name,age) self.stu_no=stu_no class Teacher(Person): def __init__(self,name,age,teacherofyear): super().__init__(name,age) self.teacherofyear=teacherofyear
Define instance object:
stu=Student('Zhang San',20,'1001') teacher=Teacher('Li Si',34,10)
Calling: info() method inherits from Person class
stu.info() teacher.info()
Output:
Zhang San 20 Li Si 34
Multiple inheritance
class A(object): pass class B(object): pass class C(A,B): pass
Unlike Java, Java can only inherit single, while Python can inherit multiple
Method rewrite
- If a subclass is not satisfied with a property or method inherited from the parent class, it can rewrite it (method body) in the subclass
- Subclass overridden methods can be overridden through super() Xxx() calls the overridden method in the parent class
class Person(object): def __init__(self,name,age): self.name=name self.age=age def info(self): print(self.name,self.age) class Student(Person): def __init__(self,name,age,stu_no): super().__init__(name,age) self.stu_no=stu_no def info(self): super().info() print(self.stu_no) stu=Student('Zhang San',25,'1001') stu.info()
The subclass overrides the info() method of the parent class
Output:
Zhang San 25 1001
11, object class
-
Object class is the parent class of all classes, so all classes have the properties and methods of object class.
-
The built-in function dir() can view all the properties of the specified object
-
Object has a "_ str _ ()" method, which is used to return a description of the "object", corresponding to the built-in function str()
It is often used in the print() method to help us view the information of the object, so we often__ str __ () Rewrite
class Student: pass stu=Student() print(dir(stu))
View all properties of an object
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
Print object
print(stu)
Output:
<__main__.Student object at 0x000001EF126D58E0>
View object information
Rewrite method first__ str __ ()
class Student: def __init__(self,name,age): self.name=name self.age=age def __str__(self): return 'My name is{0},this year{1}year'.format(self.name,self.age) stu=Student('Zhang San',26) print(dir(stu)) print(stu)
Output:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name'] My name is Zhang San. I'm 26 years old
When you rewrite the str method and print the object, you will not print the memory address of the object, but call the str function
The str method is often overridden to return a description of the object
View type
print(type(stu))
<class '__main__.Student'>
It will be the subclass type at the time of creation, not object
12, Polymorphism
In short, polymorphism means "having multiple forms". It means that even if you don't know what type of object a variable refers to, you can still call methods through this variable. During the running process, you can dynamically decide which method in the object to call according to the type of object referenced by the variable.
class Animal(object): def eat(self): print('Animals can eat') class Dog(Animal): def eat(self): print('Dogs eat bones') class Cat(Animal): def eat(self): print('Cats eat fish') class Person(object): def eat(self): print('People eat cereals') #Define a function def fun(obj): obj.eat() #Start calling function fun(Cat()) fun(Dog()) fun(Animal()) fun(Person())
Output:
Cats eat fish Dogs eat bones Animals can eat People eat cereals
In this way, different outputs can be made according to the type of object passed in
Without inheritance, polymorphism can be realized, which is different from Java
Static language and dynamic language
- The difference between static language and dynamic language about polymorphism
- Three necessary conditions for static language to realize polymorphism
- inherit
- Method rewrite
- A parent class reference points to a child class object
- Three necessary conditions for static language to realize polymorphism
- The polymorphism of dynamic language advocates "duck type". When you see a bird walking like a duck, swimming like a duck and putting it away like a duck, then the bird can be called a duck. In the duck type, we don't care about the type of object and whether it is a duck or not. We only care about the behavior of the object.
13, Special methods and properties
name | describe | |
---|---|---|
Special properties | __ dict __ | Get the dictionary of all properties and methods bound by the class object or instance object |
The following are special methods | __ len __ () | By rewriting__ len __ () method, so that the parameters of the built-in function len() can be user-defined types |
__ add __ () | By rewriting__ add __ () method, which enables the user-defined object to have the "+" function | |
__ new __ () | Used to create objects | |
__ init __ () | Initialize the created object |
Special properties
- __ dict __
class A: pass class B: pass class C(A,B): def __init__(self,name,age): self.name=name self.age=age def roar(self): print('C is roar') #Create objects of class C x=C('Jack',20) print(x.__dict__) #Attribute dictionary of instance object print(C.__dict__) #Dictionary of properties and methods of class objects #In this part of the code, X and C refer to the following methods
Output:
{'name': 'Jack', 'age': 20} {'__module__': '__main__', '__init__': <function C.__init__ at 0x00000199020715E0>, 'roar': <function C.roar at 0x00000199022821F0>, '__doc__': None}
__ class __
print(x.__class__) #Output the class to which the instance object belongs
Output:
<class '__main__.C'>
__ bases __
print(C.__bases__) # The ancestor of the parent class of the output class, because it may inherit more than one, only one level higher
Output:
(<class '__main__.A'>, <class '__main__.B'>)
__ base __
print(C.__base__) # If there are multiple parent classes of the output class, only the first one will be output and only the upper level will be selected
Output:
<class '__main__.A'>
__ mro __
print(C.__mro__) # Hierarchy of output classes
Output:
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
__ subclasses __
print(A.__subclasses__()) # Subclass of output class class D(A): pass print(A.__subclasses__())
Output:
[<class '__main__.C'>, <class '__main__.D'>]
The output is a list of subclasses
Special method
-
__ add __ () method
- Add two objects
a=20 b=100 c=a+b d=a.__add__(b) print(c) print(d)
Output:
120
120
All the numbers added here are integers
But what about two custom instance objects
class Student: def __init__(self,name): self.name=name # def __add__(self, other): # return self.name + other.name stu1=Student('Zhang San') stu2=Student('Li Si') s= stu1+stu2
report errors:
s= stu1+stu2 TypeError: unsupported operand type(s) for +: 'Student' and 'Student'
But put__ add __ () method:
class Student: def __init__(self,name): self.name=name def __add__(self, other): return self.name + other.name stu1=Student('Zhang San') stu2=Student('Li Si') s= stu1+stu2 print(stu1+stu2) print(stu1.__add__(stu2))
Output:
this one and that one this one and that one
After definition, it can be added
To realize the addition operation of two objects, it needs to be written in the parent class of two objects__ add __ () special methods
__ len __ () method
Length of output object
lst=[22,33,55,66] print(len(lst)) print(lst.__len__())
Output:
4 4
len(lst) here is a built-in function, lst__ len __ () the list object already has this method
But: the problem is that there are no custom objects
stu1 defined above cannot use this method and must be customized
class Student: def __init__(self,name): self.name=name def __len__(self): return len(self.name) stu1=Student('Zhang San') stu2=Student('Li Si') print(stu1.__len__())
Output:
2
stu2=Student('Li Si 2') print(stu2.__len__())
Output:
3
XIV__ new __ And__ init __ Demonstrate the process of creating objects
class Person(object): def __new__(cls, *args, **kwargs): print('__new__Executed, cls of id Value is{0}'.format(id(cls))) obj=super().__new__(cls) print('Of objects created id For:{0}'.format(id(obj))) return obj def __init__(self, name, age): print('__init__Called, self of id The value is:{0}'.format(id(self))) self.name=name self.age=age print('object Of this class object id For:{0}'.format(id(object))) print('Person Of this class object id For:{0}'.format(id(Person))) #Create an instance object of the Person class p1=Person('Zhang San',20) print('p1 this Person Class id:{0}'.format(id(p1)))
Output:
object Of this class object id Is: 140715602066944 Person Of this class object id As: 3186528480864 __new__Executed, cls of id The value is 3186528480864 Of objects created id As: 3186530217744 __init__Called, self of id Value: 3186530217744 p1 this Person Class id:3186530217744
15, Shallow copy and deep copy of class
Assignment of variables
- It just forms two variables, which actually point to the same object
class CPU: pass class DISK: pass class Computer: def __init__(self,cpu,disk): self.cpu=cpu self.disk=disk #(assignment of variables) cpu1=CPU() cpu2=cpu1 print(cpu1,id(cpu1)) print(cpu2,id(cpu2))
Output:
<__main__.CPU object at 0x0000013C8AB45FD0> 1359536742352 <__main__.CPU object at 0x0000013C8AB45FD0> 1359536742352
In fact, in this process, only one CPU instance object is generated, and then the address of cpu1 pointing to this instance object is assigned to cpu2
That is, CPU1 and CPU2 point to the same object
Shallow copy
-
Python copy is generally a shallow copy. When copying, the sub object content contained in the object is not copied. Therefore, the source object and the copy object will reference the same sub object
class CPU: pass class DISK: pass class Computer: def __init__(self,cpu,disk): self.cpu=cpu self.disk=disk #(assignment of variables) cpu1=CPU() cpu2=cpu1 print(cpu1,id(cpu1)) print(cpu2,id(cpu2)) #(2) Class has a shallow copy print('----------------------') disk=DISK() #Create a hard disk class object computer=Computer(cpu1,disk) # Create a computer class object #Shallow copy import copy computer2=copy.copy(computer) print(computer,computer.cpu,computer.disk) print(computer2,computer2.cpu,computer2.disk)
Output:
<__main__.CPU object at 0x00000295212D6FD0> 2839530008528 <__main__.CPU object at 0x00000295212D6FD0> 2839530008528 ---------------------- <__main__.Computer object at 0x00000295212D6970> <__main__.CPU object at 0x00000295212D6FD0> <__main__.DISK object at 0x00000295212D6F70> <__main__.Computer object at 0x00000295212D6880> <__main__.CPU object at 0x00000295212D6FD0> <__main__.DISK object at 0x00000295212D6F70>
The CPU and DISK instance objects pointed to by computer and computer2 are the same, and the points of these two sub objects are unchanged. This is called shallow copy
Deep copy
-
Use the deepcopy function of the copy module to recursively copy the sub objects contained in the object. All sub objects of the source object and the copy object are also different
#Deep copy computer3=copy.deepcopy(computer) print(computer,computer.cpu,computer.disk) print(computer3,computer3.cpu,computer3.disk)
Output:
<__main__.Computer object at 0x00000252D49A6970> <__main__.CPU object at 0x00000252D49A6FD0> <__main__.DISK object at 0x00000252D49A6F70> <__main__.Computer object at 0x00000252D49A6790> <__main__.CPU object at 0x00000252D49A64C0> <__main__.DISK object at 0x00000252D49A64F0>
It can be seen that after the deep copy of computer, the addresses of cpu and disk objects contained in the instance object of computer3 are different from those contained in computer. Not only the computer object is copied, but also the sub object cpu and disk objects are copied