Python Basics (classes and objects)

Python Basics (classes and objects)

1, Two ideas of programming

Process oriented and object-oriented

Process orientedobject-oriented
differenceThings are relatively simple and can be solved by linear thinkingThings 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
  • 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

namedescribe
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

Keywords: Python Pycharm

Added by elgordo1960 on Sun, 06 Mar 2022 12:43:18 +0200