Getting started with python 08 -- object oriented

Posted by shan169 on Tue, 28 Dec 2021 21:25:02 +0100

Python has been an object-oriented language since its design. Because of this, it is easy to create a class and object in Python.

Introduction to object oriented technology

  • Class: used to describe a collection of objects with the same properties and methods. It defines the properties and methods common to each object in the collection. An object is an instance of a class.
  • Method: a function defined in a class. Class variables: class variables are common to the entire instantiated object. Class variables are defined in the class and outside the function body. Class variables are usually not used as instance variables.
  • Data members: class variables or instance variables are used to process data related to classes and their instance objects.
  • Method override: if the method inherited from the parent class cannot meet the needs of the child class, it can be overridden. This process is called method override, also known as method override.
  • Local variable: the variable defined in the method, which only acts on the class of the current instance.
  • Instance variable: in the declaration of a class, attributes are represented by variables, which are called instance variables. Instance variables are variables decorated with self.
  • Inheritance: that is, a derived class inherits the fields and methods of the base class. Inheritance also allows the object of a derived class to be treated as a base class object. For example, there is such a design: an object of Dog type is derived from the Animal class, which simulates the "is-a" relationship (for example, Dog is an Animal).
  • Instantiation: create an instance of a class and a concrete object of the class. Object: an instance of a data structure defined by a class. The object consists of two data members (class variables and instance variables) and methods.

Compared with other programming languages, Python adds a class mechanism without adding new syntax and semantics as much as possible.

Classes in Python provide all the basic functions of object-oriented programming: the inheritance mechanism of classes allows multiple base classes, derived classes can override any method in the base class, and methods with the same name in the base class can be called.

Objects can contain any number and type of data.

1, Classes and objects

Type 1.1

Class is a general term for a group of things with the same characteristics or behavior. It is abstract and cannot be used directly.
Features are called attributes and behaviors are called methods.

Class is equivalent to the drawing when manufacturing an aircraft. It is a template and is responsible for creating objects. The syntax format is as follows:

class Class name:

    def Method 1(self, parameter list):
        pass
    
    def Method 2(self, parameter list):
        pass

A simple example:

class MyClass:
    """A simple class instance"""
    i = 12345

    def f(self):
        return 'hello world'

1.2 object

After the class is instantiated, its properties can be used. In fact, after you create a class, you can access its properties through the class name.

An object is a concrete existence created by a class and can be used directly.
The object created by which class has the properties and methods defined in which class.

Class objects support two operations: attribute reference and instantiation.
Attribute references use the same standard syntax as all attribute references in Python: obj name.
The object is equivalent to an aircraft made of drawings. Specific examples are as follows:

# Instantiation class
x = MyClass()

# Access the properties and methods of the class
print("MyClass Properties of class i Is:", x.i)  # The attribute reference is obj name
print("MyClass Class method f Output is:", x.f())
# The attribute i of MyClass class is: 12345
# The method f output of MyClass class is hello world

In program development, there should be classes before objects.

Class 1.3 design

Before using object-oriented development, we should first analyze the requirements and determine which classes need to be included in the program.
In program development, to design a class, you usually need to meet the following three elements:

Class name: the name of such things, which meets the naming method of big hump
Attribute: what are the characteristics of such things
Method: what kind of behavior does this kind of thing have


Note: attributes or methods not involved in the requirements do not need to be considered when designing classes.

2, Object oriented

2.1 encapsulation, inheritance and polymorphism

2.1. 1 package

Object oriented has three basic characteristics: encapsulation, inheritance and polymorphism.

Encapsulation: encapsulation is to hide the attributes and implementation details of the object, only disclose the interface, control the access level of attribute reading and modification in the program, and combine the abstract data and behavior (or function) to form an organic whole.

An object is an instance of an encapsulated class. Encapsulation is actually an information concealment technology.

# A simple list example
list1 = [2, 1, 7, 5, 3]
list1.sort()  # We don't know the specific implementation details of sort, but we can use it directly
list1.append(9)
print(list1)
# The result is: [1, 2, 3, 5, 7, 9]
2.1. 2 succession

Inheritance: inheritance is that a subclass inherits the characteristics and behavior of the parent class, so that the subclass object (instance) has the instance domain and method of the parent class, or the subclass inherits the method from the parent class, so that the subclass has the same behavior as the parent class.

Define a MyList class that inherits the list class, and the objects created by the MyList class can use the methods of the list class.

class MyList(list):
    pass  # Placeholder: represents that the class at this time does nothing but inherits the list class

list1 = MyList()
list1.append(3)
list1.append(4)
print(list1)
# The result is: [3, 4]

The subclass (derived class DerivedClassName) inherits the properties and methods of the parent class (base class BaseClassName). If a method or property with the same name as the parent class is defined in the subclass, the method or property corresponding to the parent class will be automatically overwritten.
An inherited instance:

import random

class Fish:
    def __init__(self):  # Record the position x,y of the fish at this time
        self.x = random.randint(0, 10)  # Position coordinates are generated randomly at the beginning
        self.y = random.randint(0, 10)

    def move(self):
        self.x -= 1  # One step to the left at a time
        print("My location is:", self.x, self.y)

class GoldFish(Fish):
    pass

class Shark(Fish):
    def __init__(self):  # Rewritten__ init__ method
       self.hungry = True

    def eat(self):
        if self.hungry:
            print("eating....")
            self.hungry = False
        else:
            print("not eating....")

fish = Fish()  # Parent object
fish.move()
fish.move()  # Can move correctly
gf = GoldFish()  # Subclass object
gf.move()
gf.move()  # Can move correctly
shark = Shark()  # Subclass object
shark.move()  # report errors

AttributeError: 'Shark' object has no attribute 'x' error will appear in this instance because the attribute in the parent class is overridden in the shark subclass__ init__ Method, the value of X in move cannot be found in the subclass.
[solution] use super(). Call the __init__ method of the parent class in the subclass.

class Shark(Fish):
    def __init__(self):
        super().__init__()  # There are parentheses after super!!
        # Use Fish__ init__ (self) can also be implemented, but the class calling the method at this time is not necessarily a subclass of Fish
        self.hungry = True

    def eat(self):
        if self.hungry:
            print("eating....")
            self.hungry = False
        else:
            print("not eating....")

Multi inheritance: class DerivedClassName(Base1, Base2, Base3), use with care!

2.1. 3 polymorphism

Polymorphism: the ability of the same behavior to have multiple different forms or forms. It refers to that the same method of a class instance (object) has different manifestations in different situations.

Class polymorphism must meet two preconditions: ① inheritance: polymorphism must occur between subclass and parent class; ② Override: the subclass overrides the method of the parent class. Here is a simple example:

class CLanguage:
    def say(self):  # Overriding the say method of the parent class
        print("Called is Clanguage Class say method")

class CPython(CLanguage):
    def say(self):  # Overriding the say method of the parent class
        print("Called is CPython Class say method")

class CLinux(CLanguage):
    def say(self):  # Overriding the say method of the parent class
        print("Called is CLinux Class say method")
        
a = CLanguage()
a.say()

a = CPython()
a.say()

a = CLinux()
a.say()

As can be seen from the above code, both CPython and CLinux inherit from the CLanguage class, and both override the say() method of the parent class. It can be seen from the running results that when the same variable a executes the same say() method, because a actually represents different class instance objects, a.say() does not call the say() method in the same class, which is polymorphic.

Python has derived a more flexible programming mechanism based on polymorphism, which is called "duck model" or "duck type".

class WhoSay:
    def say(self, who):
        who.say()
class CLanguage:
    def say(self):
        print("Called is Clanguage Class say method")

class CPython(CLanguage):
    def say(self):
        print("Called is CPython Class say method")

class CLinux(CLanguage):
    def say(self):
        print("Called is CLinux Class say method")
        
a = WhoSay()
#Call the say() method of the CLanguage class
a.say(CLanguage())
#Call the say() method of CPython class
a.say(CPython())
#Call the say() method of the CLinux class
a.say(CLinux())

In this program, by adding a who parameter to the say() function in the WhoSay class, it calls the say() method internally using the passed in who. This means that when we call the say() method in the WhoSay class, it will call the say() method in that class if we pass the instance object of which class to the WHO parameter.
Reference article here@ http://c.biancheng.net/view/5833.html

2.2 what is the self parameter?

Class methods are only different from ordinary functions -- they must have an additional first parameter name, which is conventionally called self.

class Test:
    def prt(self):
        print(self)  # Output the value of the current self
        print(self.__class__)  # Output the class pointed to by the current self
 
t = Test()  # t is the instance object created by the Test class
t.prt()  # Call the prt method of the Test class

The execution result of the above example is:

A more intuitive example:

class A:
    def fun(self):
        print("I am A Class!" + "  At this time self The value is:" + str(self) + ",It points to" + str(self.__class__))


class B:
    def fun(self):
        print("I am B Class!" + "  At this time self The value is:" + str(self) + ",It points to" + str(self.__class__))


a = A()  # Class A object
b = B()  # Class B object
# Two objects call the function fun() with the same name in different classes, and the output results are different
a.fun()
b.fun()

It can be seen that even if two objects call the function fun() with the same name in different classes, the output results are still different, because the self value of fun method is different when it is called, and the classes it points to are also different. The operation results are as follows:

2.3 built in methods of class

The special methods (construction methods) commonly used in class are shown in the following table:

2.3.1 __init__ method

__ init__ Method is a method specifically used to define which attributes a class has.

When you create an object using the class name (), the following actions are automatically performed:
    1. Allocate space for objects in memory - create objects
    2. Set the initial value for the properties of the object -- initialization method (init)
This initialization method is__ init__ () method is the built-in method of the object. Its structure is as follows:

def __init__(self):
    self.data = []

Class defines__ init__ () method, which will be called automatically by the instantiation operation of the class. Instantiate the class MyClass as follows, corresponding to__ init__ () method will be called:

x = MyClass()

__ init__ () the method can have parameters, which can be passed__ init__ () passed to the instantiation operation of the class. The following example is shown:

class Complex:
    def __init__(self, realpart, imagpart):
        self.r = realpart
        self.i = imagpart


x = Complex(3.0, -4.5)  # These two arguments are passed to realpart and imagpart respectively
print(x.r, x.i)  # Output result: 3.0 - 4.5

Application scenario: during development, if you want to set the object's properties while creating the object. We can define the attribute value we want to set as__ init__ (), and then use self. Inside the method Attribute = parameter receives externally passed parameters. When creating an object, use the class name (property 1, property 2...) Call.

2.3.2 __del__ method

In Python, when an object is created using the class name (), it is automatically called after space is allocated for the object__ init__ method. Similarly, when an object is destroyed from memory, it will be called automatically__ del__ method.

class Cat:

    def __init__(self, new_name):
        self.name = new_name
        print("%s Here we are, calling__init__method" % self.name)

    def __del__(self):
        print("%s Yes, what is called at this time is__del__method" % self.name)


# tom is a global variable
tom = Cat("Tom")
print(tom.name)  # Output Tom

# del keyword can delete an object
del tom  

The execution result of the above code is:

Life cycle: an object is created from the calling class name (), and the life cycle begins the creation of an object__ del__ Once a method is called, the life cycle ends.
Application scenario:__ del__ () if you want to do something else before the object is destroyed, you can consider using__ del__ () method.

2.4 public and private

To define a private variable in python, you only need to add two underscores "_" before the variable name or function name, Then the variable or function becomes private. It cannot be called outside the class, but only inside the class.
The following is a public variable call:

# name public
class Person:
    name = 'Zhai'

p = Person()
print(p.name)  # Output Zhao

After changing the public variable name to a private variable:

# name private
class Person:
    __name = 'Zhai'  # Change name to private

p = Person()
print(p.__name)

The running result will report an error because private variables cannot be called directly. As follows:

So how do we get the value of private variables? In fact, we can use instances_ Class name__ Variable name to get the value. As follows:

class Person:
    __name = 'Zhai'  # Change name to private

p = Person()
print(p._Person__name)  # Note that the class name is preceded by only one_
# The running result is Zhao

In fact, the internal logic of the above steps is consistent with the use of the get method, that is, the code shown below.

class Person:
    __name = 'Zhai'
    def getName(self):
        return self.__name
p = Person()
# print(p.__name)  # This statement will report an error
print(p.getName())  # When the variable is private, the get method must be called to get the value
# The running result is Zhao

Combination of class 2.5

Class composition, that is, when a class is instantiated, the instance of another class is passed in as a parameter, so that the two instances can be associated.

When there are significant differences between classes, and the smaller class is the component required by the larger class, it is better to use composition.
[example] define a class called pool. There should be turtles and fish in the pool. Call the method in the pool to display the number of turtles and fish in the pool.

class Turtle:
    def __init__(self, x):
        self.num = x


class Fish:
    def __init__(self, x):
        self.num = x


class Pool:
    def __init__(self, x, y):
        self.turtle = Turtle(x)
        self.fish = Fish(y)

    def print_num(self):
        print("Turtles in the pool %d One, little fish %d Bar!"% (self.turtle.num, self.fish.num))

pool = Pool(1, 10)
pool.print_num()
# The running result is: 1 turtle and 10 small fish in the pool!

In this instance, the instances of Fish class and Turtle class are used as parameters in the Pool class.

2.6 binding

Python strictly requires that methods can be called only when they need an instance. This restriction is actually what Python calls a binding concept.
If the method does not contain self in parentheses, you can directly use the class object, that is, the class name Method name call.

class Test:
    def print_Test():
        print("not correct!")

Test.print_Test()
# The running result is: not correct!

However, once the method in the class is called with the instance object of the class, it is not feasible.

class Test:
    def print_Test():
        print("not correct!")

# Test.print_Test()
t = Test()  # Instance object
t.print_Test()
# Error reported: TypeError: print_Test() takes 0 positional arguments but 1 was given

If a method has self in parentheses, it cannot be called directly with a class object, but only with an instance object.

class Test2:
    def setXY(self, x, y):
        self.x = x
        self.y = y
    def printXY(self):
        print(self.x, self.y)

tt = Test2()
print(tt.__dict__)  # View the dictionary composed of all attribute names and attribute values inside the instance object
print(Test2.__dict__)  # View the dictionary composed of all attribute names and attribute values inside the class object
tt.setXY(4, 5)  # An instance object calls a method in a class
print(tt.__dict__)  # At this time__ dict__ There is a value in
print(Test2.__dict__)  # Not in class objects, because binding makes these two objects only belong to instance objects

The running result of the above code is:

3, Built in functions related to classes and objects

3.1 issubclass(class, classinfo)

The issubclass() method is used to determine whether the parameter class is a subclass of the type parameter classinfo.

class A:
    pass

class B(A):
    pass

print(issubclass(B, A))  # B is a subclass of A
# True

3.2 isinstance(object, classinfo)

isinstance() function to determine whether an object is a known type, similar to type().
Parameters:
Object – instance object.
classinfo – can be a direct or indirect class name, a primitive type, or a tuple of them.

class A:
    pass

class B(A):
    pass

b = B()
print(isinstance(b, B))  # B is an instantiated object of class B
print(isinstance(b, A))  # Class B inherits class A
# The results are all True

3.3 hasattr(object, name)

The hasattr() function is used to determine whether the object contains the corresponding attribute.
Parameters:
Object – object.
Name – string, attribute name.

class C:
    def __init__(self, x=0):
        self.x = x

c = C()
print(hasattr(c, 'x'))  # Be sure to add a string!!
# True

3.4 getattr(object, name[, default])

The getattr() function is used to return an object property value.

class C:
    def __init__(self, x=0):
        self.x = x

c = C()
print(getattr(c, 'x'))  # Existence value output value is 0
print(getattr(c, 'y', "The property you accessed does not exist!"))  # Output: the property you accessed does not exist!

3.5 property(fget[, fset[, fdel[, doc]]]])

The property() function returns a property value in a new class.
Parameters:
fget – function to get property value
fset – function that sets the value of the attribute
fdel – delete attribute value function
doc – attribute description information

class Test:
    def __init__(self, size=10):
        self.size = size
    def getSize(self):
        return self.size
    def setSize(self, value):
        self.size = value
    def delSize(self):
        del self.size
    x = property(getSize, setSize, delSize)

t = Test()
print(t.x)  # This step represents getting the value of x, corresponding to the getSize method
t.x = 18  # This step represents setting the value of x, corresponding to the setSize method
print(t.x)
del t.x  # This step represents deleting x, corresponding to the delSize method
print(t.x)

For more use of built-in methods, please refer to@ https://www.runoob.com/python/python-built-in-functions.html

Topics: Python