Detailed Python object-oriented programming (8)

Python founder of Guido van Rossum (Guido van Rossum). During Christmas 1989, Guido van Rossum in Amsterdam in order to pass the time, determined to develop a new script interpreter, language as ABC one of the inheriting .Python is pure free software, the source code and the interpreter CPython follow the GPL (GNU General Public License) protocol philosophy of the python:. python advocate: "elegant", "clear", "simple", Python is the simplest and most elegant and most obvious way to solve the problem.

Object-oriented programming provides a new way of thinking, the focus of software design is no longer a logical flow of the program, but the relationship between software or program objects and objects, using object-oriented programming thoughts, better able to design software architecture, software maintenance modules, and easy reuse of frameworks and components.

Python support process-oriented, object-oriented, functional programming and other programming paradigms, and does not force us to use any programming paradigm, we can write any procedural programming procedure used in the preparation of a small program, basically not a problem but for medium and large projects, object-oriented will give us a lot of advantages. the next will be combined with object-oriented features Python syntax and the basic concepts of object-oriented programming to explain.

Introduction to Object-Oriented Programming

Object-oriented, OOP英文全称(Object-Oriented Programming)is a highly efficient programming ideas, object-oriented technology has become the mainstream of software design and technology development in the field of object-oriented programming is a programming mode, use the "class" and "object" to achieve, so the object-oriented programming in fact, the use of "class" and "object" class is a template, the template can contain multiple methods (functions), to achieve a variety of functions in the method, the object is an example of a template created by example the method may be performed in the object classes, each object has a method of the same, but the respective data may be different.

In object-oriented design, a programmer can create any new types that may be described and wherein the data of each object included in the class is abstract some objects, hiding the complexity of the internal structure and achieve the object, the class variables and functions of two parts, called the class variable 数据成员, the function is called class 成员函数, it is an abstract class objective things, and the object is the entity class is instantiated.

Simply put, "object-oriented" is a programming paradigm, and programming paradigm is summed up in a different programming features of programming, the saying goes, all roads lead to Rome, also said that we can use different methods to reach the final purposes, but some way to compare fast, safe and effective, some methods are inefficient and unsatisfactory results. Similarly, programming but also to solve the problem, but to solve the problem can have a variety of different perspectives and ideas, to which the former Some universal and effective programming mode attributed to the "paradigm", common programming paradigms are:

● process-oriented programming: OPP (Oriented Programing Procedure)
● object-oriented programming: of OOP (Object Oriented Programing)
● function-oriented programming: FP (Functional Programing)

Object-oriented programming has three objectives: reusability, flexibility, scalability, and features several major objectives:

● Package: hide implementation details, so the code modular code mask implementation details, only the external interfaces
● inheritance: by extending the existing class code reuse, to avoid duplication of the same code written
● Polymorphism: polymorphism in order to achieve reuse of the interface is such that a plurality of flexible calls between different classes

Here, we have the basic object-oriented role, characteristics, application scenarios introduced over, here is a personal note, can not do everything, if you want to understand, consult the manual to learn some of their own, most of the above excerpt from focus on books, then we will focus on 封装,继承,多态such as core object-oriented concepts will be explained.

Object-oriented -> Package

Packaging is one of the main features of object-oriented, and the main characteristics of the object class concept. Simply put, the class that encapsulates logical entity data and a method of operating the data, partial data and methods it is exposed outwardly, block individual implementation details, in addition, in an internal objects, some data or methods can be private, these private data or methods is not allowed access to the outside world. in this way, the object of the internal data provide different levels of protection.

Package, which is the objective things packaged as an abstract class, and the class can put their data and methods allow only trusted class or object manipulation of unreliable information hiding, encapsulation is generally through the data encapsulated in the class, and by object or self acquisition, and other object-oriented language similar, but also for data encapsulated by the constructor, it means, we will write together some functions similar function, the convenience of our calling and maintenance.

◆ simple class package ◆

In Python, classes are defined by class关键字, followed by class followed by the class name, class name is usually the beginning of the word capitalized, followed by ()小括号, you can write in the parentheses (要继承的类名称)indicate the class which is inherited from the class down, how can two 父类(基类), usually without the right to inherit the class, use object类, this is the ultimate all classes inherit a class, you can not write, do not write, then the default is loaded.

>>> import sys
>>> import os
>>>
>>> class lyshark(object):
...     def __init__(self,name,age,sex):
...             self.name = name
...             self.age = age
...             self.sex = sex
...
>>>
>>> temp=lyshark("lyshark","22","Man")
>>> print("姓名:%s   年龄:%s   性别:%s"%(temp.name,temp.age,temp.sex))
姓名:lyshark   年龄:22   性别:Man

These are created by a lysharkclass shown above __init__()is called initialization process (or method of construction), when the class is instantiated, the process (although it is a function of the form, but not in a class called the function called a method) is automatically executed, some initialization actions, so we write here __init__(self,name,age,sex)is to give it set these properties when you create a role that is assigned to do some initialization work.

Goes parameters selfworkflow is this.

● an open space directed lyshark variable name, which is equivalent to a function pointer in memory
● instantiate the class which is performed first __init__(), will be automatically executed after transferring the parameters to the internal variables
● then automatically execute __init__()construction method, the memory it of space, then self.* = *the same two variables data

Creating an object is called instantiation, or to see the code above, temp=lyshark()this sentence is to lyshark类instantiate, when an object is created, comprising three characteristic areas: handle, properties and methods of objects into the handle for distinguishing different objects, when the object is created, the object acquires a storage space, that is, the object identification address storage space, member variables and member functions of the class attributes and methods of an object corresponds.

◆ with a public property package ◆

Class properties and methods composition, attribute classes data package, and methods of a class object has behavior, said class generally by the function (instance method) and variables (class variables), with the following using public property package data members, can be seen outside the class, we can use the temp.name="xxoo"method to modify the value of this data members, and then call the print function again, it is found that the data had been altered, this is clearly not safe enough.

>>> import sys
>>> import os

# =====================以下内容是类的定义====================
>>> class lyshark():
...     def __init__(self,name,age):          #构造函数,初始化数据
...             self.name = name              #封装的数据成员
...             self.age = age
...
...     def my_print(self):                   #封装的成员函数
...             print("我的名字是:%s 我的年龄是:%s"%(self.name,self.age))
...
# =========================================================
>>>
>>> temp=lyshark("wangrui","22")              #类的实例化,将参数传入类中
>>> temp.my_print()                           #调用类中的指定方法,打印数据
我的名字是:wangrui 我的年龄是:22
>>>
>>> print(temp.name)                          #直接调用类中的数据成员
wangrui
# ===============改变数据成员,再次调用看看===================
>>> temp.name="xxoo"
>>> temp.my_print()
我的名字是:xxoo 我的年龄是:22
# =========================================================

Small summary: 1. The public properties or static properties, can also be accessed directly through the class direct direct access by way of example .2 modify public properties through an instance of the class, for instance actually added a and. public property name of the class members of the same attributes, the real public property is not affected, so it does not affect the value of the public property of .3 other instances retrieved. modify public properties by category, it will certainly be changes in public the original value of the property, he is the class of all instances are affected.

◆ ◆ the use of private property package

In the small example above, we also found some defects, then take a look at the package of skills private property, private property and a member of the same attributes, is __init__declared method, but the property names need to be double-underlined __开头, private property is a special member properties, not only allows internal inherited by subclasses (method members or private methods), and disallow directly accessed through instance object or instance of the object class on the outside, an object instance, short sentence: 私有属性只有类的内部可以调用.

>>> import os
>>> import sys

# =====================以下内容是类的定义====================
class lyshark():
        name = "lyshark"                    #定义公有属性(类变量,可共享数据)
        __age = 22                          #定义私有属性(类变量)

        def __init__(self):                 #定义构造函数,初始化数据
                self.__like = "soccer"      #定义私有实例属性(实例变量)
                self.hobby = "xxoo"         #定义公有实例属性

        def my_print(self):                 #定义公有函数,外部可以调用
                print("我的名字: %s"%self.name)
                print("我的年龄: %s"%self.__age)
                print("我的爱好: %s"%self.__like)
                print("其他: %s"%self.hobby)

    def __new_test(self):               #定义私有函数,只能内部类调用
        print("hello world")

        def __del__(self):                  #定义析构函数,清理数据
            self.__nobody = "end"
            #print("函数执行结束,销毁无用的数据. %s"%self.__nobody)

# =================(公有/私有)方法的调用====================
>>> temp=lyshark()                          #实例化对象
>>> temp.my_print()                         #调用类中方法(公有方法)
我的名字: lyshark
我的年龄: 22
我的爱好: soccer
其他: xxoo

>>> temp.__new_test()                       #调用私有方法,则会报错
# =================(公有/私有)属性的调用====================
>>> print(lyshark.name)                     #调用公有属性则成功
lyshark
>>> print(lyshark.__age)                    #调用私有属性,则会报错
>>> print(lyshark.__like)
# =========================================================

Small Summary: By 公有属性and 私有属性comparison of the data, we can clearly see the gap between them, it boils down to this, a private variable can not be accessed directly through the class, two private variables can not be accessed directly by the object instance, 3. the private variables can be accessed by members of the method .4 class variable may generally be used for data sharing between the two instantiated, the instance variables only apply to the current instance.

◆ The object class encapsulate ◆

Some frequently used in addition to the above package, and a package more difficult to understand format, this is the following, it means the object is an instance of the class as a parameter to another class, then in another class, we can call to access the data members and member functions are passed class friends.

import os
import sys

class main(object):
        def __init__(self,name,obj):          #OBJ参数用来接收对象
                self.name=name
                self.obj=obj

class uuid(object):
        def __init__(self,uid,age,sex):
                self.uid=uid
                self.age=age
                self.sex=sex

temp=uuid(1001,22,"Man")                     #首先给UUID类初始化
lyshark=main("lyshark",temp)                 #将生成的TEMP对象传递给main
# =========================================================
>>> lyshark.name
'lyshark'
>>> lyshark.obj.uid                          #最后通过多级指针的方式访问数据
1001
>>> lyshark.obj.sex
'Man'
>>> lyshark.obj.age
22


Object-oriented -> Inheritance

Object-oriented programming (OOP) language is a major feature is the "inheritance", inheritance refers to the ability, it can use all the features of an existing class, and write again without the need to extend these capabilities to the case of the original class .

Inheritance is one of the important object-oriented features, you can create a new class through inheritance, which aims to use or modify the behavior of existing classes, the original class is called the parent class or super class, the new class is called the subclass or derived class, when the inheritance mechanism can reuse code, inherited the essence of the method is the parent class of all copy to subclasses, Python can inherit inside multiple inheritance, through inheritance, the parent class function can be obtained, inheritance, if duplicate the parent class method, giving priority to find their own (sub-category).

◆ ◆ inherit the base class ordinary function

The following is a basic small example, the relationship can be inherited, the first base()is a base class, and expand()is a derived class, derived from base(), as though derived column has no function, but we can still call the printf () function to print incoming data, it can explain the function of the base class is inherited inside.

import os
import sys

class base():               #这个类是基类
        def __init__(self,name,age):
                self.name = name
                self.age = age

        def printf(self):
                print("姓名:%s  年龄:%s"%(self.name,self.age))


class expand(base):         #新建类expand继承base基类的方法
        pass
# =========================================================
>>> temp=expand("lyshark","22")
>>> temp.printf()
姓名:lyshark  年龄:22

◆ ◆ inherited base class constructor

Of course, we can also inherit the parent constructor, and add a new property field to the appropriate sub-category, you can also directly super()approach a direct function of the body in a subclass's parent class inside called and returns the results to the the caller.

Direct extends Constructors: new expand()subclass, inheriting base()the base class constructor and capable of printing the data in the parent class attributes subclass.

import os
import sys

class base():
        def __init__(self,name,age):
                self.name = name
                self.age = age

        def printf(self):
                print("姓名:%s  年龄:%s"%(self.name,self.age))


class expand(base):
        def __init__(self,name,age):
                super(expand,self).__init__(name,age)      #推荐使用本功能实现继承
                #base.__init__(self,name,age)              #此处和上面实现的功能相等

        def printf(self):
                print("姓名:%s  年龄:%s"%(self.name,self.age))

# =========================================================
>>> temp=base("lyshark","22")
>>> temp.printf()
姓名:lyshark  年龄:22
>>> temp=expand("lyshark","22")
>>> temp.printf()
姓名:lyshark  年龄:22

Add a new field: the parent class base()based on the rewriting of the original field, subclasses expand()add a new field sex, and be able to pass parameters.

import os
import sys

class base():                                           #定义的父类
        def __init__(self,name,age):
                self.name = name
                self.age = age

        def printf(self):
                print("姓名:%s  年龄:%s"%(self.name,self.age))


class expand(base):                                     #定义的子类
        def __init__(self,name,age,sex):
                super(expand,self).__init__(name,age)   #继承父类的属性
                self.sex = sex                          #新添加的一个属性

        def printf(self):
                print("姓名:%s  年龄:%s  性别:%s "%(self.name,self.age,self.sex))

# =========================================================
>>> temp=base("lyshark","22")                          #原始基类,没有第三个字段
>>> temp.printf()
姓名:lyshark  年龄:22

>>> temp=expand("lyshark","22","Man")                  #在不影响父类情况下,重写新的字段
>>> temp.printf()
姓名:lyshark  年龄:22  性别:Man 

Inherited from the parent class function (mandatory): If you want to use a method wherein the parent class in the subclass, may be implemented using the following method.

import os
import sys

class base(object):
        def printf(self):
                print("================================")
                print("执行函数....")
                print("================================")
                return 0

class expand(base):
        def fun(self):
                ret=super(expand,self).printf()      #强制调用父类中的printf方法
                return ret                           #将结果返回给调用者

# =========================================================
>>> temp=base()
>>> temp.printf()                                    #调用基类的方法
================================
执行函数....
================================

>>> obj=expand()                                     #在子类中调用基类方法
>>> ret=obj.fun()                                    #将返回值付给ret并打印
>>> print(ret)
================================
执行函数....
================================
0

◆ multi-class inheritance and multiple inheritance ◆

Simple multiple inheritance: Here we implement a simple multiple inheritance, where we will explain the code in their order of execution, ado, see figure below.

import os
import sys

class A:
    def fun(self):
        print("我是A类里面的函数")

class B:
    def fun1(self):
        print("我是B类里面的函数1")
    def fun2(self):
        print("我是B类里面的函数2")

class C(A,B):
    def fun(self):
        print("我是C类里面的函数")

# =========================================================
>>> temp=C()
>>> temp.fun()        #默认调用C类,如果C里面有fun()函数则默认执行自身
我是C类里面的函数      #如果自身没有,才会去基类里面去找fun()函数的存在

>>> temp.fun1()       #由于C类中没有这个方法,它会去B或A类里面去找
我是B类里面的函数1      #这也为我们重写函数提供了可能性,我们只需修改C类且名称相同即可实现重写

Complex multiple inheritance: The following is important and difficult, in other source are so dry, belongs to inherit if the nested develop a new program, it is best not to do it, and finally even himself ignorant of the force.

import os
import sys

class A:
    def bar(self):
        print('bar')
        self.f1()

class B(A):
    def f1(self):
        print('b')

class C():
    def f1(self):
        print('c')

class D(B):
    def f1(self):
        print('d')

class E(C,D):
    pass

temp=D()
temp.bar()

Multi-class inheritance (examples): Multiple inheritance is also a way to solve the problem, we are here by way of example, to demonstrate what multiple inheritance scenario, we add the following three categories are Person(人类)used as a parent class, you create two derived class, one is Teacher(老师), the other Student(学生)two classes, two classes derived Person(人类), are all human beings have a common attribute.

1. We first create a base class Person()to describe the history of our range, of course, humans have some common attributes such as name, age, whether the teacher has the students.

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def walk(self):
        print('%s is walking...' % self.name)
        
    def talk(self):
        print('%s is talking...' % self.name )

2. Derive a class based on the above base on the Teachersubclass, the use of several of the properties and methods of the parent class.

class Teacher(Person):
    def __init__(self, name, age, level, salary):
        super(Teacher, self).__init__(name, age)
        self.level = level
        self.salary = salary

    def teach(self):
        print('%s is teaching...' % self.name)

3. Finally, create a class of students Student, public some basic properties and methods are equally and parent.

class Student(Person):
    def __init__(self, name, age, class_):
        Person.__init__(self, name, age)
        self.class_ = class_

    def study(self):
        print('%s is studying...' % self.name)

4. Finally instantiated directly, passing two parameters, see the results of printing, it is well understood.

>>> t1 = Teacher('张老师', 33, '高级教师', 20000)
>>> s1 = Student('小明', 13, '初一3班')

>>> t1.talk()
>>> t1.walk()
>>> t1.teach()

>>> s1.talk()
>>> s1.walk()
>>> s1.study()

张老师 is talking...
张老师 is walking...
张老师 is teaching...
小明 is talking...
小明 is walking...
小明 is studying...


Object-oriented -> Polymorphism

Polymorphism (polymorphisn) is set up to allow you to become a parent and one or more sub-objects equal to his skill, after the assignment, the parent object can be assigned to it according to the characteristics of the current sub-objects operate in different ways polymorphic role: we know that packaging can hide implementation details, so that the code is modular, inheritance can be extended existing code modules, their purpose is to achieve 代码的重用, while the polymorphism is in order to achieve another purpose and that is 接口的重用, polymorphic role is to class inheritance and derived the time to ensure that the use of "family tree" of a property right called when instances of a class in any one sentence, is to reuse interface.

import os
import sys

class Animal(object):
    def __init__(self, name):
        self.name = name

class Cat(Animal):
    def talk(self):
        print('%s: 喵喵喵!' %self.name)

class Dog(Animal):
    def talk(self):
        print('%s: 汪!汪!汪!' %self.name)
 
def func(obj):            #这里制定一个接口,后期直接调用它
    obj.talk()

# =========================================================
>>> c1 = Cat("catcat")
>>> d1 = Dog("dogdog")

>>> func(c1)              #这里调用相同的方法,传入的数据不同
catcat: 喵喵喵!
>>> func(d1)              #这里调用相同的方法,传入的数据不同
dogdog: 汪!汪!汪!


Object-oriented -> Packaging

Mentioned above, the object-oriented concept too, are typically packaged in class 数据(数据成员)and operation of 数据的方法(成员函数)these two things is formed composed of a prototype of a category, that is, data attributes, and the attribute has been described above is nothing less than that over several classification, 公有属性/类变量, 成员属性/实例变量and 私有属性, in addition to these properties, methods now say to us in the class, the class is divided into the following categories:

● a member method: Typically, the members thereof with similar properties, by way of example is to access the object class, the first member of the process is usually written argument self, to indicate which is a member method
● Private Method: double underscore (__)beginning members the method is a private method, and is similar to private property, private instance of an object can only be accessed internally and can not be inherited by subclasses
method ● class: use @classmethodto decorate the members of the class method method is called, is defined as a class method, the class can only access variable, not instance variables
● static methods: using @staticmethodmembers to decorate method is called the static methods, static methods do not have any association with the class, and used to write kits normally
● property methods: a method to become static properties, so you can go visit this access method as member properties, and can not by ()parentheses, passing parameters

◆ ◆ class method

The above also briefly described, usually above the member function if we add @classmethodto decorate member methods called class methods, which requires the first argument must be a current class, and 公有属性/静态属性similar, except by way of example the object may be access can also be accessed directly through the class name to, and the first parameter represents the current class, usually written as cls, another should be noted that, class methods can only access the public property and can not access the member properties, so the first cls is representative of transmission parameters of the current class, rather than indicative of self instance object.

import os
import sys

class lyshark(object):
    name="wangrui"                       #赋值等待被调用
    age="22"
    sex="Man"

    def __init__(self,x,y,z):
        self.x=x
        self.y=y
        self.z=z

    @classmethod                         #声明下方的函数为类方法
    def printf(cls):                     #此函数只能调用类变量,而不能调用成员属性
        print("姓名:%s 年龄:%s 性别:%s"%(cls.name,cls.age,cls.sex))

# =========================================================
>>> temp=lyshark("100","100")
>>> temp.printf()
姓名:wangrui 年龄:22 性别:Man

If we modify variables than the print function invocation instance variable, an error occurs because the decorator classmethodexists, if masked decorator code, you can call it a success, but the call is no longer a class variable data, but the data in the instance variables.

    def __init__(self,x,y,z):
        self.x=x
        self.y=y
        self.z=z

    #@classmethod                      #此装饰器存在,不允许调用实例变量
    def printf(self):
        print("姓名:%s 年龄:%s 性别:%s"%(self.x,self.y,self.z))

# =========================================================
>>> temp=lyshark("lyshark","33","Man")
>>> temp.printf()
姓名:lyshark 年龄:22 性别:Man

◆ ◆ static method

The above brief also shows that, under normal circumstances, if we add the above member functions @staticmethodmember of ways to decorate is called the static method, a static method is a function of class, no instance of static method is mainly used to store logic of the code, logic belonging to the class, but the class itself, and no relationship, i.e. in a static method, the operation does not involve the properties and methods of the class. it will be appreciated, for a static method is independent, a simple function it just hosted the namespace of a class, easy to use and maintain, under normal circumstances we can use it to implement a proprietary toolkit.

import os
import sys

class lyshark(object):

    @staticmethod
    def sum(x,y):
        return x+y

    @staticmethod
    def sub(x,y):
        return x-y

# =========================================================
>>> #temp=lyshark()               #这里无需实例化

>>> text=lyshark.sum(10,20)
>>> print("两数之和:%s"%text)
两数之和:30

>>> text=lyshark.sub(100,50)
>>> print("两数之差:%s"%text)
两数之差:50

The above is a typical example of a small package, because other data we can not call class, so direct it as a toolbox is the most appropriate use of it, of course, this feature so far in the development did not use Zenmo too.

◆ ◆ Properties Methods

property is a special property, will perform some function (function) to access it and returns the value, he can become a method static properties, you can access the member properties as like to access this method, and can not by ()parentheses, transfer parameter, which must be first parameter is the current instance of the object, and the method must have a return value.

import os
import sys

class lyshark(object):
    def __init__(self,name,weight,height):
        self.name=name
        self.weight=weight
        self.height=height

    @property
    def foo(self):
        return self.weight + self.height

# =========================================================
>>> temp=lyshark("wangrui",75,1.88)
>>> print(temp.foo)             #此处我们直接调用这个属性,并没有传递参数
76.88

Small example above, we can see an example of a class later, when calling internal function foo, and not add the brackets, but still call succeeded, use this feature to follow the principle of universal access, that is outside shielding the details, just the same as calling variables to use it to give users the feeling is called a class variable.

Because the new class has three access methods, we can access several features of their properties, respectively, for the three methods defined on the same property: access, modify, delete, look at the following code:

import os
import sys

class lyshark(object):

    @property
    def get(self):
        print("get 函数运行了我...")

    @get.setter
    def get(self,value):
        print("set 设置参数运行了我,传递的参数是: %s"%value)

    @get.deleter
    def get(self):
        print("工作结束了,可以删除数据了")

# =========================================================
>>> temp = lyshark()                    #实例化
>>> temp.get                            #调用get属性,则会执行get()函数
get 函数运行了我...

>>> temp.get = 'hello'                  #设置属性则会执行get.setter函数
set 设置参数运行了我,传递的参数是: hello

>>> del temp.get                        #删除工作,则会走get.deleter函数
工作结束了,可以删除数据了

Let's look at a specific example, we can directly call obj.priceto get the price of goods can also be modified by an assignment statement and other commodity prices.

class Goods(object):

    def __init__(self):
        # 原价
        self.original_price = 100
        # 折扣
        self.discount = 0.8

    @property
    def price(self):
        # 实际价格 = 原价 * 折扣
        new_price = self.original_price * self.discount
        return new_price

    @price.setter
    def price(self, value):
        self.original_price = value

    @price.deltter
    def price(self, value):
        del self.original_price

# =========================================================
>>> obj = Goods()
>>> obj.price         # 获取商品价格
>>> obj.price = 200   # 修改商品原价
>>> del obj.price     # 删除商品原价


Guess you like

Origin www.cnblogs.com/LyShark/p/11297595.html
Recommended