zoukankan      html  css  js  c++  java
  • 第五十节,面向对象基本介绍

    一,面向对象基础1
    c#、Java:只能用面向对象编程
    Ruby、python、php:函数编程 + 面向对象

    1.面向过程编程2
      就是程序最底层的实现过程
    2.函数式编程3
      就是将最底层的实现过程封装到函数里,调用函数的方法编程
    3面向对象编程4
      就是将若干函数封装到一个类里,调用类来实现里面的函数方法

    注意:面向对象不是所有情况都适用 5

    面向对象编程6
    需要定义一个类 ,将功能函数写在类里,这样类里面的函数就叫做,实现一个类功能的方法,要使用这个类的方法时,创建这个类的对象赋值给一个变量,通过对象变量找到这个类下面的功能函数来实现(功能)的方法

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    class fgjk: #定义一个类,在类里写函数来实现类的方法
        def f1(self,a): #方法1
            return a + 1
        def f2(self,b): #方法2
            pass
        def f3(self,c): #方法3
            pass
    
    a1 = fgjk() #创建类对象赋值给一个变量
    a2 = a1.f1(3) #调用类下面的一个函数传入参数,来实现一个功能,叫做方法
    print(a2) #打印出这个方法的结果
    
    #输出fgjk类下面的f1()方法
    # 4

    class关键字,定义一个类7

    功能:定义一个类

    使用方法:class 类名称:

    格式:class fgjk:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    class fgjk: #定义一个类,在类里写函数来实现类的方法
        def f1(self,a): #方法1
            return a + 1
        def f2(self,b): #方法2
            pass
        def f3(self,c): #方法3
            pass

    定义好类后,将功能函数(方法)写在类里,注意:类里面的函数有一个必写值self8

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    class fgjk: #定义一个类,在类里写函数来实现类的方法
        def f1(self,a): #方法1
            return a + 1
        def f2(self,b): #方法2
            pass
        def f3(self,c): #方法3
            pass

    self是一个形式参数,这个形式参数是用来,在执行类方法时接收类对象返回值的,9

    注意:类对象的返回值是由python自动当做实参,传入类方法函数的self,不需要我们写,由python自动完成

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    """定义类和类的方法"""
    class fgjk: #定义一个类,在类里写函数来实现类的方法
        def f1(self,a): #方法1
            print("打印self接收的类对象值",self)
            return a #返回值
    """创建类的对象和是使用类的方法"""
    a1 = fgjk() #创建类对象赋值给一个变量
    print("打印类对象值",a1)
    #注意:类对象的值是由python自动当做实参,传入类方法函数的,不需要我们写,由python自动完成,相当于下面写的a1.f1(a1,3)
    a2 = a1.f1(3) #调用类下面的一个函数传入参数,来实现一个功能,叫做方法
    print("打印返回值",a2) #打印出这个方法的结果
    
    # 输出
    # 打印类对象值 <__main__.fgjk object at 0x0000006685D37160>
    # 打印self接收的类对象值 <__main__.fgjk object at 0x0000006685D37160>
    # 打印返回值 3

    定义好类和写好函数方法后,创建这个类的对象赋值给一个变量,通过变量找到这个类下面的功能函数来实现(功能)的方法  , 创建类对象也叫做(创建Foo类的实列)10

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    """定义类和类的方法"""
    class fgjk: #定义一个类,在类里写函数来实现类的方法
        def f1(self,a): #方法1
            return a + 1
        def f2(self,b): #方法2
            pass
        def f3(self,c): #方法3
            pass
    
    """创建类对象和使用类的方法"""
    a1 = fgjk() #创建类对象赋值给一个变量
    a2 = a1.f1(3) #调用类下面的一个函数传入参数,来实现一个功能,叫做方法
    print(a2) #打印出这个方法的结果
    
    #输出fgjk类下面的f1()方法
    # 4

    面向对象原理图11

    封装12

    封装就是给对象封装普通字段

    面向对象封装之,在类的对象里封装变量和变量值,非主流方法【不推荐】13
    就是在类的对象里封装变量和变量值,封装后使用类函数方法时不需要传值,在类函数方法里通过self来获取类对象里的值即可

    给类对象添加变量:创建对象变量.要添加的变量名称 = 变量值  如a1.zhi =  xx

    类方法函数获取对象变量:在方法函数里通过接收对象的self来获取,self.添加的类对象变量名称,这样就可以获取到类对象的值

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    """面向对象封装之,给类对象封装变量和变量值"""
    class fgjk: #定义一个类,在类里写函数来实现类的方法
        def f1(self): #方法1
            b = self.zhi + 5 #获取类对象里的zhi变量的值加5
            c = b + self.zhi2 #用b结果加类对象里的zhi2变量值
            return c
    """创建类的对象和使用类的方法"""
    a1 = fgjk() #创建类对象赋值给一个变量
    a1.zhi = 5 #给类对象封装一个变量和值
    a1.zhi2 = 10 #给类对象封装一个变量和值
    a2 = a1.f1() #执行类方法
    print(a2) #打印出方法结果
    # 输出
    # 20

    面向对象封装之,在类的对象里封装变量和变量值原理图14

    __init__()构造方法,面向对象封装之,给类对象封装变量和变量值,主流方法 15

    __init__(self)类方法函数,如果类里有定义__init__(self)类方法函数,创建对象后会自动执行__init__(self)方法函数的

    使用方法:__init__(self,后面可以定义变量类接收对象传值然后封装到对象)

    就是不在从类对象那里封装变量和值,从类的__init__(self)方法,向对象封装变量和值,因为只要创建对象后,python就会默认执行类的__init__(self)方法,然而对象的返回值是自动通过对象传值给类方法的self形式参数的,所以可以根据这个形式参数接收到的对象,向对象里封装变量和变量值

    # -*- coding:utf-8 -*-
    """面向对象封装之,给类对象封装变量和变量值,主流方法"""
    class fgjk: #定义一个类,在类里写函数来实现类的方法
        def __init__(self):
            print(self)
            self.adc = "你好" #通过self接收到的对象,向对象里封装变量和变量值
        def f1(self):
            print(self.adc)
    """创建类的对象和使用类的方法"""
    a1 = fgjk() #创建类对象赋值给一个变量,并把类对象返回值传给类里面的方法函数的self形式参数
    a1.f1() #执行类的方法函数
    # 输出
    # <__main__.fgjk object at 0x000000A5E652C518>
    # 你好

    通过类方法的self给对象封装变量原理图16

    __init__()构造方法,面向对象封装之,给类对象封装变量和变量值,主流方法2【推荐】17

    # -*- coding:utf-8 -*-
    """面向对象封装之,给类对象封装变量和变量值,主流方法"""
    a = "变量值"
    class fgjk: #定义一个类,在类里写函数来实现类的方法
        def __init__(self,b):
            print(self)
            self.adc = b #通过self接收到的对象,向对象里封装变量和变量值
        def f1(self):
            print(self.adc)
    """创建类的对象和使用类的方法"""
    a1 = fgjk(a) #创建类对象赋值给一个变量,并把类对象返回值传给类里面的方法函数的self形式参数
    a1.f1() #执行类的方法函数
    # 输出
    # <__main__.fgjk object at 0x000000A5E652C518>
    # 变量值

    主流方法2【推荐】原理图18

    注意:我们一般都是用构造方法2

    __del__(self)解释器销毁对象时自动调用,我们只需要知道一些就行,这是python自动完成的,叫做析构方法19

    封装总结20

    使用场景,当同一类型的方法具有相同参数时,直接封装到对象即可

    使用场景2:把类当做模板,创建多个对象(每个对象内封装的数据可以不一样)

    创建类对象,和__init__()构造封装对象变量,叫做初始化

    给对象封装的变量,叫做给对象创建普通字段

    继承21

    继承就是在定义类b时,可以在b类名称后面加上()括号里写上另外一个a类的名称,这样b类就会继承a类里的方法22

    1.子类(派生类)、继承父类(基类)中的所有功能23
    2.Python类可以同时继承多个父类(基类)(c#/Java不可以)24

    3.继承的优先级,继承里有相同方法的优先级25

      子类(派生类)、和父类(基类)同时存在一个方法是时,优先找子类(派生类),

      如果是一个类继承了多个类,而且继承的多个类中有同样的方法是,优先从子类(派生类)()括号里的父类(基类)左边优先

      如果是嵌套式继承,也就是一个类继承了多个基类,并且多个基类又继承了多个基类,这时是自己本身类优先,然后是上一级基类左边第一个优先,再者是左边第一个基类的上级基类优先,再者是左边第二基类优先以此类推

      也就是说,首先是自身优先,然后是基类左边优先,然后是基类左边深度优先,以此类推的

      如果嵌套式继承,最后有两个类都继承了同一个基类,这个被两个类继承的类不在深度查找,是最后查找这个类的

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    class lei: #定义lei类
        def __init__(self,wb = ""): #接收定义lei对象里的传值
            self.wb = wb #将定义lei对象里的传值封装到lei对象里
        def f1(self):
            print("f1",self.wb) #打印f1和,lei对象里封装的wb变量
        def f2(self):
            print("f2")
        def f3(self):
            print("f3")
    
    class lei2(lei): #定义lei2类并继承lei类的方法
        def __init__(self,wb2 = ""): #接收定义lei2对象里的传值
            self.wb2 = wb2 ##将定义lei2对象里的传值封装到lei2对象里
        def j1(self):
            print("j1")
        def j2(self):
            print("j2",self.wb2) #打印j2和,lei2对象里封装的wb2变量
        def j3(self):
            print("j3")
    
    a = lei("你好") #创建lei类对象,并传值到lei类__init__方法
    a.f1() #执行类里的f1()方法
    
    b = lei2("我好") #创建lei2类对象,并传值到lei2类__init__方法
    b.f3() #执行lei2类继承的lei里的f3()方法
    b.j2() #执行lei2类里的j2()方法
    
    # 输出
    # f1 你好
    # f3
    # j2 我好

    继承原理图26

    继承优先级说明图27

    自身优先图28

    基类左边第一个优先图29

    左边深度优先图30

     最后有两个类都继承了同一个基类,这个被两个类继承的类不在深度查找,是最后查找这个类的31

    继承重点,self.XXX()继承容易错点,如果一个类继承了多个基类,并且基类里有self.XXX()方法,self实际就是创建的对象,self.xxx()就是又回到了创建对象的类里去找xxx()方法,如果创建的自身类里没有xxx()方法,就又从继承基类的左边第一个开始查找,在之深度等,以此按照前面说的优先级执行32

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    class a: #定义a类
        def __init__(self,zhi = ""):
            self.zhi = zhi
        def f1(self):
            print("a")
    class b: #定义b类
        def __init__(self,zhi = ""):
            self.zhi = zhi
        def b1(self):
            self.f1()
    class c: #定义c类
        def __init__(self,zhi = ""):
            self.zhi = zhi
        def f1(self):
            print("c")
    class d(b,c,a): #定义d类
        def __init__(self,zhi = ""):
            self.zhi = zhi
    fsa = d("传值") #创建d类对象
    fsa.b1() #执行d类对象的类里面的b1()方法,类里面没有b1方法,就到继承的基类左边第一个b类里去找b1方法,找到b1方法执行,然而b1里是执行的对象里面的f1方法,这样就又回到了d类里去找f1方法
    # 输出
    # c

    self.XXX()继承原理图33

     

    super()内置函数【推荐】,在一个类里获取上一级父类基类的,__init__方法里的对象封装值,注意只能获取上一级基类的__init__方法里的对象封装值34

    使用方法:super(子类派生类名称,self).__init__()

    格式:super(b,self).__init__()

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    class c: #定义a类
        def __init__(self):
            self.zf = "狗shi"
        def f1(self):
            print("c")
    class a: #定义a类
        def __init__(self):
            self.zhi = "动物"
        def f1(self):
            print("a")
    class b(a): #定义b类
        def __init__(self):
            self.zh = ""
            super(b,self).__init__() #获取上一级父类基类的,__init__方法里的对象封装值
            print(self.zhi) #打印出获取到的,上一级父类基类的,__init__方法里的对象封装值
        def b1(self):
            print("b")
    c = b()
    c.f1()
    # 输出
    # 动物
    # a

    被获取类名称.__init__(self)在一个类里获取另外一个类的__init__方法里的对象封装值,注意,可以获取有继承关系的,也可以获取无继承关系的类35

    使用方法:被获取类名称.__init__(self)

    格式:c.__init__(self)

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    class c: #定义a类
        def __init__(self):
            self.zf = "狗shi"
        def f1(self):
            print("c")
    class a: #定义a类
        def __init__(self):
            self.zhi = "动物"
        def f1(self):
            print("a")
    class b(a): #定义b类
        def __init__(self):
            self.zh = ""
            c.__init__(self) #在一个类里获取另外一个类的__init__方法里的对象封装值,注意,可以获取有继承关系的,也可以获取无继承关系的类
            print(self.zf) #打印获取到的,另外一个类的__init__方法里的对象封装值
        def b1(self):
            print("b")
    c = b()
    c.f1()
    # 输出
    # 狗shi
    # a

    多态36

    多态就是多种形态

    python自身支持多态
    多态的简单理解就是,定义一个函数,创建类对象,把类对象当做实际参数传给函数的形式参数,在函数里通过形式参数接收到的类对象来执行对象类里的方法,也就是向函数传不同的对象,就执行不同对象类的方法

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    """多态,多种形态"""
    class ab: #定义ab类
        def __init__(self,zhi = ""): #定义__init__方法接收类对象传的值
            self.zhi = zhi #将类对象传值封装到对象里吧,给对象封装一个字段
        def f1(self): #定义类方法
            print(self.zhi) #打印ab类对象里封装的zhi字段
    
    class cd: #定义cd类
        def __init__(self,zhi = ""): #定义__init__方法接收类对象传的值
            self.zhi = zhi #将类对象传值封装到对象里吧,给对象封装一个字段
        def f1(self): #定义类方法
            print(self.zhi) #打印cd类对象里封装的zhi字段
    
    def ef(fang): #定义一个函数,设置一个形式参数接收类对象
        fang.f1() #接收对象,并执行对象的类里面的f1()方法
    
    ef(ab("你好")) #执行函数,创建ab类对象当做实参传值给ef函数
    ef(cd("我好")) #执行函数,创建cd类对象当做实参传值给ef函数
    
    # 输出
    # 你好
    # 我好

     多态原理图37

    面向对象的进阶38

    成员39
    类下面的方法为类的成员
    对象下面的封装字段为对象成员

    利用反射来操作类里的成员40

    hasattr()内置反射函数,到指定类查找指定方法是否存在,和到指定的对象下查找,对象下的封装变量是否存在,或者到指定对象查找对象类里的指定方法,存在返回True,否则返回False

    注意:对象有对象指针指向了类,所有也能用hasattr()函数通过对象来查找类里的方法,所以推荐通过对象来查找,既可以查找类又可以查找对象下的字段

    使用方法:hasattr(要查找的类名称或对象名称,字符串形式要查找的方法名称或对象封装名称)41

    格式:hasattr(c,"f1")

    到指定类查找指定方法是否存在

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    class c: #定义a类
        def __init__(self):
            self.zf = "狗shi"
        def f1(self):
            print("c")
    class a: #定义a类
        def __init__(self):
            self.zhi = "动物"
        def f1(self):
            print("a")
    fa = hasattr(c,"f1") #hasattr()内置函数,到指定类查找指定方法是否存在,和到指定的对象下查找,对象下的封装变量是否存在,存在返回True,否则返回False
    print(fa)
    # 输出
    # True

    到指定的对象下查找对象下的封装变量是否存在

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    class c: #定义a类
        def __init__(self):
            self.zf = "狗shi"
        def f1(self):
            print("c")
    class a: #定义a类
        def __init__(self):
            self.zhi = "动物"
        def f1(self):
            print("a")
    fa = hasattr(a(),"zhi") #hasattr()内置函数,到指定类查找指定方法是否存在,和到指定的对象下查找,对象下的封装变量是否存在,存在返回True,否则返回False
    print(fa) 
    # 输出
    # True

    到指定对象查找对象类里的指定方法

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    class c: #定义a类
        def __init__(self):
            self.zf = "狗shi"
        def f1(self):
            print("c")
    class a: #定义a类
        def __init__(self):
            self.zhi = "动物"
        def f1(self):
            print("a")
    fa = hasattr(a(),"f1") #hasattr()内置函数,到指定类查找指定方法是否存在,和到指定的对象下查找,对象下的封装变量是否存在,存在返回True,否则返回False
    print(fa)
    # 输出
    # True

    getattr()内置反射函数,到指定的对象下找到,对象下的封装变量赋值给一个变量,或者到指定对象找到对象类里的指定方法赋值给一个变量42

    注意:对象有对象指针指向了类,所有也能用hasattr()函数通过对象来查找类里的方法,所以推荐通过对象来查找,既可以查找类又可以查找对象下的字段

    使用方法:getattr(要查找的对象,字符串形式要查找的方法名称或对象封装名称)

    格式:fa = getattr(c(),"f1")

    到指定对象找到对象类里的指定方法赋值给一个变量,并执行方法

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    class c: #定义a类
        def __init__(self):
            self.zf = "狗shi"
        def f1(self):
            print("c")
    class a: #定义a类
        def __init__(self):
            self.zhi = "动物"
        def f1(self):
            print("a")
    fa = getattr(c(),"f1") #getattr()内置反射函数,到指定的对象下找到,对象下的封装变量赋值给一个变量,或者到指定对象找到对象类里的指定方法赋值给一个变量
    fa() #执行找到的类方法
    # 输出
    # c

    到指定的对象下找到,对象下的封装变量赋值给一个变量

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    class c: #定义a类
        def __init__(self):
            self.zf = "狗shi"
        def f1(self):
            print("c")
    class a: #定义a类
        def __init__(self):
            self.zhi = "动物"
        def f1(self):
            print("a")
    fa = getattr(c(),"zf") #getattr()内置反射函数,到指定的对象下找到,对象下的封装变量赋值给一个变量,或者到指定对象找到对象类里的指定方法赋值给一个变量
    print(fa)
    # 输出
    # 狗shi

    用反射操作面向对象成员43

    根据字符串方式的面向对象模块,和字符串方式的类方法,用反射来执行面向对象44

    面向对象模块

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class c: #定义a类
        def __init__(self):
            self.zf = "狗shi"
        def f1(self):
            print("c")
    class a: #定义a类
        def __init__(self):
            self.zhi = "动物"
        def f1(self):
            print("a222")

    反射操作面向对象模块里的成员

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    """根据字符串方式的面向对象模块,和字符串方式的类方法,用反射来执行面向对象"""
    a = "lib.ska.mk"    #面向对象模块路径
    b = "f1"            #类方法名称
    c = __import__(a,fromlist=True)     #反射方式导入面向对象模块
    d = hasattr(c.a(),b)                #查找模块里的a类里是否有f1方法,返回布尔值
    if d:                               #判断模块里的a类里是否有f1方法
        f1 = getattr(c.a(),b)           #如果有就找到f1方法赋值给一个变量
        f1()                            #执行找到a类里的f1方法
    else:
        print("a类里没有f1方法")
    
    # 输出
    # a222

    静态字段45

    静态字段,也就是在类里面定义变量,提供类里的所有方法调用,这样能很好的实现多个类有一个相同数据的情况46

    注意:静态字段是通过,类名称.静态字段名称来访问的,对象封装的普通字段,是通过self.普通字段名称来访问的

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        shux = "动物"
        def __init__(self,zhu): #初始化__init__接收对象传值
            self.zhu = zhu #将对象传值封装到对象里
        def f1(self): #定义方法
            print(a.shux, self.zhu) #打印类的静态字段和对象封装的普通字段
        def f2(self): #定义方法
            print(a.shux, self.zhu) #打印类的静态字段和对象封装的普通字段
        def f3(self): #定义方法
            print(a.shux, self.zhu) #打印类的静态字段和对象封装的普通字段
    s = a("") #创建对象并传值
    s.f1() #执行对象类里的f1()方法
    f = a("") #创建对象并传值
    f.f2() #执行对象类里的f2()方法
    b = a("") #创建对象并传值
    b.f3() #执行对象类里的f3()方法
    # 输出
    # 动物 猫
    # 动物 狗
    # 动物 猪

    静态字段原理图47

    静态方法48

    就是在类里定义普通函数,函数上面用上装饰符@staticmethod,静态方法不需要传self参数,静态方法通过类来访问,不需要创建对象就可以访问

    @staticmethod在类里声明一个静态方法49

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu): #初始化__init__接收对象传值
            self.zhu = zhu #将对象传值封装到对象里
        @staticmethod #定义静态方法
        def f1(): #静态方法
            print("静态方法")
        def f3(self): #定义方法
            print(a.shux, self.zhu)
    a.f1()
    # 输出
    # 静态方法

    静态方法原理图50

    类方法51

    就是在类里定义一个函数,函数上面用上装饰符@classmethod,函数里有一个必写形式参数cls用来接收类名称

    @classmethod在类里声明一个类方法52

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu): #初始化__init__接收对象传值
            self.zhu = zhu #将对象传值封装到对象里
        @classmethod #定义类方法
        def f1(cls): #自动将类名称传值给cls形参
            print(cls) #打印cls接收到的类名称
        def f3(self): #定义方法
            print(a.shux, self.zhu)
    a.f1()
    # 输出
    # <class '__main__.a'>

    类方法原理图53

    特性方法54

    @property特性方法55

    就是在类里定义一个普通方法函数,函数上面用上装饰符@property,函数里有一个必写形式参数self用来接收对象地址,也可以给方法封装普通字段

    特性方法与普通方法的区别:就是执行特性方法函数时不用写()括号,特性方法就是将普通方法伪造成通过对象获取的字段,特殊方法获取到返回值后是可以重新赋值的

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu): #初始化__init__接收对象传值
            self.zhu = zhu #将对象传值封装到对象里
        @property #声明特性方法
        def f1(self): #定义特性方法
            te = "{}方法".format(self.zhu)
            print(te)
        def f3(self): #定义方法
            print(a.shux, self.zhu)
    s = a("特性")
    s.f1 #执行对象类里的f1特性方法
    # 输出
    # 特性方法
    s.f1 = "重新赋值" #特殊方法获取到返回值后是可以重新赋值的

    特性方法原理图56

    设置特性方法:就是给特性方法设置值57

    @方法名称.setter给特性方法设置值58

    就是在类里的特性方法下面,写一个给特性方法名称一样的方法函数,函数上面用上装饰符@方法名称.setter,在方法里设置一个形式参数来接收,执行设置特性方法传值,执行设置特性方法时,将特性方法 = 要设置的值即可

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu): #初始化__init__接收对象传值
            self.zhu = zhu #将对象传值封装到对象里
        @property #声明特性方法
        def f1(self): #定义特性方法
            te = "{}方法".format(self.zhu)
            print(te)
        @f1.setter  #设置特性方法
        def f1(self,v): #设置特性方法
            print(v) #打印设置的特性方法值
            self.zhu = v #将设置的特性方法值替换对象封装的普通字段
    s = a("特性")
    s.f1 #执行对象类里的f1特性方法
    s.f1 = "设置特性方法值"
    s.f1
    # 输出
    # 特性方法
    # 设置特性方法值
    # 设置特性方法值方法

     设置特性方法原理图59

    成员修饰符60
    修饰成员的使用权限对成员:静态字段、普通字段、普通方法、静态方法、类方法、特性方法,进行成员权限修饰61
      公有:就是没加__修饰符的成员,既可以在类里面访问,也可以通过类或者对象外部访问
      私有:就是加上__修饰符的成员,通过对象或者类无法外部访问,只能在类内部访问,外部要想访问必须在类的内部定义一个公有方法,在公有方法里执行要想访问的私有成员,通过公有方法来间接的访问私有成员,注意:一个类的私有方法只有类自己内部可以使用, 而且无法被继承。

    __类成员修饰符,用于修饰类的成员私有权限,用了__修饰符的私有成员只有类自身内部可以访问。62

     静态字段修饰符63

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        __jt = "静态字段"
        def __init__(self,zhu = ""): #初始化__init__接收对象传值
            self.zhu = zhu #将对象传值封装到对象里
        def f1(self):
            print(a.__jt)
        def f2(self):
            pass
    #print(a.__jt) #静态字段加修饰符后外部不可以访问
    f = a() #定义对像
    f.f1() #可以通过类里的f1方法间接访问
    # 输出
    # 静态字段

    普通字段修饰符64

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu = ""): #初始化__init__接收对象传值
            self.__zhu = zhu #将对象传值封装到对象里,封装普通字段
        def f1(self):
            print(self.__zhu)
        def f2(self):
            pass
    f = a("普通字段") #定义对象
    #print(f.zhu) #普通字段加修饰符后外部不可以访问
    f.f1() #通过类里的f1方法可以间接访问对象里封装的普通字段
    # 输出
    # 普通字段

    普通方法修饰符65

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu = ""): #初始化__init__接收对象传值
            self.__zhu = zhu #将对象传值封装到对象里,封装普通字段
        def __f1(self):
            print("普通方法")
        def f2(self):
            self.__f1()
    f = a() #定义对象
    #f.__f1() #普通方法加修饰符后外部不可以访问
    f.f2() #通过类里的f2方法可以间接访问加修饰符的f1普通方法
    # 输出
    # 普通方法

    静态方法修饰符66

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu = ""): #初始化__init__接收对象传值
            self.__zhu = zhu #将对象传值封装到对象里,封装普通字段
        @staticmethod #定义静态方法
        def __f1():
            print("静态方法")
        def f2(self):
            a.__f1()
    #a.__f1() #静态方法加修饰符后外部不可以访问
    f = a() #定义对象
    f.f2() #通过类里的f2方法可以间接访问加修饰符的f1静态方法
    # 输出
    # 静态方法

    类方法修饰符67

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu = ""): #初始化__init__接收对象传值
            self.__zhu = zhu #将对象传值封装到对象里,封装普通字段
        @classmethod #定义类方法
        def __f1(cls):
            print("类方法",cls)
        def f2(self):
            a.__f1()
    #a.__f1() #类方法加修饰符后外部不可以访问
    f = a() #定义对象
    f.f2() #通过类里的f2方法可以间接访问加修饰符的f1类方法
    # 输出
    # 类方法 <class '__main__.a'>

    特性方法修饰符68

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu = ""): #初始化__init__接收对象传值
            self.__zhu = zhu #将对象传值封装到对象里,封装普通字段
        @property #定义特性方法
        def __f1(self):
            print("特性方法")
        def f2(self):
            self.__f1
    f = a() #定义对象
    #f.__f1 #特性方法加修饰符后外部不可以访问
    f.f2() #通过类里的f2方法可以间接访问加修饰符的f1特性方法
    # 输出
    # 特性方法

    成员修饰符之特殊手段,外部访问类的私有成员【不到万不得已不使用】69

    方法:类名称或者对象名称._类名称__私有字段名称

    格式:a._a__jt

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        __jt = "静态字段"
        def __init__(self,zhu = ""): #初始化__init__接收对象传值
            self.zhu = zhu #将对象传值封装到对象里
        def f1(self):
            print(a.__jt)
        def f2(self):
            pass
    print(a._a__jt) #特殊手段外部访问类的私有成员
    # 输出
    # 静态字段

    类成员之特殊方法70

    __call__方法是类里的一个特殊方法,当类里定义了这个方法时,创建对象后在对象后面加上()括号,也可以在对象变量后面加括号是一样的,会自动执行类里的__call__方法71

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu = ""): #初始化__init__接收对象传值
            self.zhu = zhu #将对象传值封装到对象里
        def __call__(self, args): #定义__call__方法
            print(args,self.zhu)
        def f2(self):
            pass
    f = a("方法")("__call__")
    # 输出
    # __call__ 方法
    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu = ""): #初始化__init__接收对象传值
            self.zhu = zhu #将对象传值封装到对象里
        def __call__(self, args): #定义__call__方法
            print(args,self.zhu)
        def f2(self):
            pass
    f = a("方法")
    f("__call__")
    # 输出
    # __call__ 方法

    __getitem__方法是类里的一个特殊方法,当类里定义了这个方法时,创建对象后在对象后面加上[]中括号,会自动执行类里的__getitem__方法,并将[]中括号里的值传给__getitem__方法的形式参数。72

    注意:对象后面加上[1:2:3],也是执行类的__getitem__方法

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu = ""): #初始化__init__接收对象传值
            self.zhu = zhu #将对象传值封装到对象里
        def __getitem__(self, item): #创建__getitem__方法
            s = self.zhu + item #将创建对象封装的普通字段,加上执行__getitem__方法时的传值,相加后并返回值
            return s #返回值
        def f2(self):
            pass
    f = a(10) #创建对象传值
    b = f[10] #执行__getitem__方法并传值给__getitem__方法
    print(b) #打印__getitem__方法返回值
    # 输出
    # 20

    对象后面加上[1:2:3],也是执行类的__getitem__方法 73

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu = ""): #初始化__init__接收对象传值
            self.zhu = zhu #将对象传值封装到对象里
        def __getitem__(self, item): #创建__getitem__方法,将[]中括号里的数据重新封装成一个slice对象传给item
            print(item) #打印接收到的slice对象元素
        def f2(self):
            pass
    f = a() #创建对象传值
    b = f[10:12:3] #执行__getitem__方法并传值给__getitem__方法
    print(b) #打印__getitem__方法返回值
    # 输出
    # 20

    __setitem__方法是类里的一个特殊方法,当类里定义了这个方法时,创建对象后在对象后面加上[xxx]=xxx中括号等于,会自动执行类里的__setitem__方法,并将[xxx]=xxx中括号和等于里的值传给__setitem__方法的形式参数74

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu = ""): #初始化__init__接收对象传值
            self.zhu = zhu #将对象传值封装到对象里
        def __setitem__(self, key, value): #定义__setitem__方法
            print(key,value) #打印[xxx] = xxx 传值
        def f2(self):
            pass
    f = a() #创建对象传值
    f[""] = "" #执行__setitem__方法并传值给__setitem____方法
    # 输出
    # 键 值

    __delitem__方法是类里的一个特殊方法,当类里定义了这个方法时,创建对象后在对象后面加上del对象名称[xxx]中括号,会自动执行类里的__delitem__方法,并将[xxx]中括号里的值传给__delitem__方法的形式参数75

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu = ""): #初始化__init__接收对象传值
            self.zhu = zhu #将对象传值封装到对象里
        def __delitem__(self, key): #定义__delitem__方法
            print("删除",key) #操作[xxx]里传来的值
        def f2(self):
            pass
    f = a() #创建对象传值
    del f[""] #执行__delitem__方法,并传值给__delitem__方法
    # 输出
    # 删除 键

    __iter__方法是类里的一个特殊方法,当类里定义了这个方法时,创建对象后只要for循环对象,会自动执行类里的__iter__方法,如__iter__方法里是一个生成器,for循环就会循环出生成器里的结果76

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __iter__(self): #定义__iter__方法
            yield 1 #生成器
            yield 2
            yield 3
            yield 4
        def f1(self):
            pass
    s = a() #创建对象
    for i in s: #循环对象
        print(i) #循环打印出生成器里的数据
    # 输出
    # 1
    # 2
    # 3
    # 4

     

    __str__方法是类里的一个特殊方法,当类里定义了这个方法时,创建对象后只要print打印对象或者str(对象)时就,会自动执行类里的__str__方法77

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义类
        def __init__(self,vas): #定义__init__方法,接收对象传值
            self.fds = vas #将对象传值封装成对象普通字段
        def __str__(self): #定义__str__方法
            return self.fds #返回对象里的普通字段
        def f1(self):
            pass
    f = a("str方法")
    print(f) #打印对象时自动执行__str__方法
    
    b = str(f) #str(对象)时也会执行__str__方法
    print(b)
    # 输出
    # str方法
    # str方法

    __dict__查看对象或者类里的成员78

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    class a: #定义a类
        def __init__(self,zhu = ""): #初始化__init__接收对象传值
            self.zhu = zhu #将对象传值封装到对象里
        def __getitem__(self, item): #创建__getitem__方法,将[]中括号里的数据重新封装成一个slice对象传给item
            print(item) #打印接收到的slice对象元素
        def f2(self):
            pass
    f = a("zhi") #创建对象传值
    print(f.__dict__) #查看对象里的成员
    print(a.__dict__) #查看类里的成员
    # 输出
    # {'zhu': 'zhi'}
    # {'__init__': <function a.__init__ at 0x00000036345AE510>, 'f2': <function a.f2 at 0x00000036345AE620>, '__getitem__': <function a.__getitem__ at 0x00000036345AE598>, '__weakref__': <attribute '__weakref__' of 'a' objects>, '__dict__': <attribute '__dict__' of 'a' objects>, '__module__': '__main__', '__doc__': None}

    可以忽略,源码创建类原理79

     __new__ python创建类源码方法80

     __metaclass__ python创建类源码方法81

    阅读以下代码:

    class Foo(object):
     
        def __init__(self):
            pass
     
    obj = Foo()   # obj是通过Foo类实例化的对象

    上述代码中,obj 是通过 Foo 类实例化的对象,其实,不仅 obj 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象

    如果按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。

    print type(obj) # 输出:<class '__main__.Foo'>     表示,obj 对象由Foo类创建
    print type(Foo) # 输出:<type 'type'>              表示,Foo类对象由 type 类创建

    所以,obj对象是Foo类的一个实例Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建。

    那么,创建类就可以有两种方式:

    普通方式

    class Foo(object):
     
        def func(self):
            print 'hello wupeiqi'

    特殊方式(type类的构造函数)

    def func(self):
        print 'hello wupeiqi'
     
    Foo = type('Foo',(object,), {'func': func})
    #type第一个参数:类名
    #type第二个参数:当前类的基类
    #type第三个参数:类的成员

    ==》 类 是由 type 类实例化产生

    那么问题来了,类默认是由 type 类实例化产生,type类中如何实现的创建类?类又是如何创建对象?

    答:类中有一个属性 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程。

    class MyType(type):
    
        def __init__(self, what, bases=None, dict=None):
            super(MyType, self).__init__(what, bases, dict)
    
        def __call__(self, *args, **kwargs):
            obj = self.__new__(self, *args, **kwargs)
    
            self.__init__(obj)
    
    class Foo(object):
    
        __metaclass__ = MyType
    
        def __init__(self, name):
            self.name = name
    
        def __new__(cls, *args, **kwargs):
            return object.__new__(cls, *args, **kwargs)
    
    # 第一阶段:解释器从上到下执行代码创建Foo类
    # 第二阶段:通过Foo类创建obj对象
    obj = Foo()

    重点总结82

    面向对象三大特性:83
    封装、继承、多态

    成员:84
    字段:普通字段(每个对象都有一份相同数据时)、静态字段(每个对象都不同的数据时)
    方法:静态方法(无需使用对象封装的内容时)、类方法(需要获取对象名称时)、普通方法(使用对象中的数据时)
    特性方法:特性方法(将方法伪造成字段时)
    特殊方法:对象后写上执行属性,就会自动执行特殊方法

    类成员访问方法:85
    通过类访问的有:静态字段,静态方法,类方法
    通过对象访问的有:普通字段,普通方法,特性方法
    一般有self的方法用对象访问,无self的方法用类来访问

    成员修饰符:86
    修饰成员的使用权限对成员:静态字段、普通字段、普通方法、静态方法、类方法、特性方法,进行成员权限修饰
    公有:就是没加__修饰符的成员,既可以在类里面访问,也可以通过类或者对象外部访问
    私有:就是加上__修饰符的成员,通过对象或者类无法外部访问,只能在类内部访问,外部要想访问必须在类的内部定义一个公有方法,在公有方法里执行要想访问的私有成员,通过公有方法来间接的访问私有成员
    ,注意:一个类的私有方法只有类自己内部可以使用,而且无法被继承。

    特殊方法对应的执行属性:87
    类名称(xxx):创建对象并执行类的__init__方法
    对象变量(xxx):执行类的__call__方法
    对象变量[xxx]:执行类的__getitem__方法
    对象变量[x:x:x]:执行类的__getitem__方法
    对象变量[xxx]=xxx:执行类的__setitem__方法
    del对象变量[xxx]:执行类的__delitem__方法
    for循环对象变量:执行类的__iter__方法

  • 相关阅读:
    归一化与标准化的概念与区别
    深度学习中的优化器学习
    yolo3与yolo-tiny
    给tensorflow1.x estimator 添加timeline分析性能
    python 爬取百度图片
    TensorFlow 高性能数据输入管道设计指南
    TensorRT加速tensorflow模型(使用Tensorflow内置tensorRT,避免写自定义Plugin)
    21.Pod的limit和request和资源监控收集服务Heapster
    20.调度器,预选策略和优选策略
    8.docker的安全性
  • 原文地址:https://www.cnblogs.com/adc8868/p/5876539.html
Copyright © 2011-2022 走看看