zoukankan      html  css  js  c++  java
  • python 学习笔记9(面向对象)

    面向过程、函数式、面向对象

    • 面向过程:根据业务逻辑从上到下写垒代码
    • 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
    • 面向对象(Object Oriented Programming,OOP):对函数进行分类和封装,让开发“更快更好更强...

        面向过程

          是用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处。

        函数式编程

          增强代码的重用性和可读性

        面向对象

          面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对 象”的使用。

    创建类和对象

      类就是一个模板,模板里可以包含多个函数,函数里实现一些功能

      对象则是根据模板创建的实例,通过实例对象可以执行类中的函数

    class bar:             #定义一个类
        def f(self,arg):   #方法
            print(arg)
            return 2
    obj = bar()           #中间人
    a = obj.f(1)              #类的调用
    print(a)
    
    class bar:             #定义一个类
        def f(self,arg):   #方法
            print(self,self.name,self.age,arg)
            return 2
    obj = bar()           #中间人                     #self 就是对象(中间人)
    print(obj)
    obj.name="liu"                                     #<__main__.bar object at 0x0000000000A74160>
    obj.age = 18                                                 #<__main__.bar object at 0x0000000000A74160> liu 18 1
    obj.f(1)
    #类的调用
    
    obj2= bar()           #中间人                     #self 就是对象(中间人)
    print(obj2)
    obj2.name="Alex"                                    #<__main__.bar object at 0x0000000000D04240>
    obj2.age = 38                                        #<__main__.bar object at 0x0000000000D04240> Alex 38 1
    obj2.f(1)
    View Code

    创建方法

    #普通方法
    class bar:             #定义一个类
        def f(self,arg):   
            print(arg)
            return 2
    obj = bar()           
    a = obj.f(1)             
    print(a)               #1,2
    
    
    #构造方法
    
    class Person:
        def __init__(self,name,age):
            self.n = name
            self.a = age
        def foo(self):
            print(self.n,self.a)
    liu =Person("liu",18)
    print(liu)                              #<__main__.Person object at 0x00000000006EA630>
    liu.foo()                             #liu 18
    View Code

    在构造方法中只要创建了对象,则第一时间会执行——init——方法

    执行顺序

    面向对象三大特性

    一 、封装

    #封装
    class Person:
        def __init__(self,name,age):          
            self.n = name
            self.a = age
            self.x = "o"
        def foo(self):
            print(self.n,self.a,self.x)
    liu =Person("liu",18)
    li = Person("li",20)
    print(liu)                              #<__main__.Person object at 0x00000000007B42E8>
    liu.foo()                               #liu 18 o
    封装

    封装在self中,即:封装在调用的对象中(本例中的liu、li),本例为构造方法,只要创建对象,python内部会第一时间自动执行

    对于面向对象的封装来说,其实就是使用构造方法将内容封装到 对象 中,然后通过对象直接或者self间接获取被封装的内容

    二 、继承

      继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。

      1、继承
        class 父类:           父类雅名:基类
          pass
        class 子类(父类):    子类雅名:派生类
          pass

    #继承
    class A:
        def a1(self):
            print("1111111111")
        def a2(self):
            print("2222222222")
    class B(A):
        def b1(self):
            print("3333333333333")
    obj = B()
    obj.b1()                  #3333333333333
    obj.a1()                 #1111111111
    obj.a2()                  #2222222222
    继承

      

      2、重写
        防止执行父类中的方法

    class A:
        def a1(self):
            print("1111111111")
        def a2(self):
            print("2222222222")
    class B(A):
        def b1(self):
            print("3333333333333")
        def a2(self):
            print("44444444444")
    obj = B()
    obj.b1()         #3333333333333
    obj.a1()         #1111111111
    obj.a2()         #44444444444
    重写

        

        如果一定要执行父类中的方法

    class A:
        def a1(self):
            print("1111111111")
        def a2(self):
            print("2222222222")
    class B(A):
        def b1(self):
            print("3333333333333")
        def a2(self):
            super(B,self).a2()
            #A.a2(self)          #和上边的super方法一样,推荐使用super方法
            print("44444444444")
    obj = B()
    # obj.b1()
    # obj.a1()
    obj.a2()        #2222222222          44444444444
    View Code

    (1)super(子类, self).父类中的方法(...)
    (2)父类名.父类中的方法(self,...)

      3、self永远是执行方法的调用者

      4、Python中支持多继承

      a. 左侧优先
      b. 一条道走到黑
      c. 同一个根时,根最后执行

     

    #多父类的方法中
    #1.从左到右
    #2.一条道走到头
    #3.多父类有共同父类,先左走到最高层(父类的共同父类不执行),然后#后层继续,最后执行父类的共同父类
    class Basrequest:
        pass
    class re_request():
        def f(self):
            print("FFFFFFFFFFFF")
            self.h()       #self 相当于obj(zilei的),所以当执行obj.f()  时先打印FFFFFFFFFFFF,下边的调用self.h(),相当于obj.h(),先执行mini中的h方法,
        def h(self):
            print("HHHHHHHHHHHH")
    class mini:
        def h(self):
            print("mininmininmini")
    class zilei(mini,re_request):
        pass
    obj = zilei()
    #obj.h()                 #mininmininmini
    obj.f()                   #FFFFFFFFFFFF
                              #mininmininmini
    多继承

    对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。

    Python的类可以继承多个类,Java和C#中则只能继承一个类

    Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先广度优先

      当类是经典类时,多继承情况下,会按照深度优先方式查找

      当类是新式类时,多继承情况下,会按照广度优先方式查找

    经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了跟多的功能,也是之后推荐的写法,从写法上区分的话,如果 当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。

    class D:
    
        def bar(self):
            print 'D.bar'
    
    
    class C(D):
    
        def bar(self):
            print 'C.bar'
    
    
    class B(D):
    
        def bar(self):
            print 'B.bar'
    
    
    class A(B, C):
    
        def bar(self):
            print 'A.bar'
    
    a = A()
    # 执行bar方法时
    # 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错
    # 所以,查找顺序:A --> B --> D --> C
    # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
    a.bar()
    经典类多继承
    class D(object):
    
        def bar(self):
            print 'D.bar'
    
    
    class C(D):
    
        def bar(self):
            print 'C.bar'
    
    
    class B(D):
    
        def bar(self):
            print 'B.bar'
    
    
    class A(B, C):
    
        def bar(self):
            print 'A.bar'
    
    a = A()
    # 执行bar方法时
    # 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错
    # 所以,查找顺序:A --> B --> C --> D
    # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
    a.bar()
    新式类多继承

    三 、多态

      Pyhon不支持Java和C#这一类强类型语言中多态的写法,python中是原生多态  

    # Java
    string v = 'alex'
    
    def func(string arg):
    print(arg)
    
    func('alex')
    func(123)                      #会报错
    
    # Python 
    v = 'alex'
    
    def func(arg):
    print(arg)
    
    
    func(1)
    func('alex')
    View Code

     

    面向对象---适用场景

      如果多个函数中有一些相同参数时,转换成面向对象

     class DataBaseHelper:
        
            def __init__(self, ip, port, username, pwd):
                self.ip = ip
                self.port = port
                self.username = username
                self.pwd = pwd
            
            def add(self,content):
                # 利用self中封装的用户名、密码等   链接数据
                print('content')
                # 关闭数据链接
            
            def delete(self,content):
                # 利用self中封装的用户名、密码等   链接数据
                print('content')
                # 关闭数据链接
            
            def update(self,content):
                # 利用self中封装的用户名、密码等   链接数据
                print('content')
                # 关闭数据链接
                
            def get(self,content):
                # 利用self中封装的用户名、密码等   链接数据
                print('content')
                # 关闭数据链接
    
    s1 = DataBaseHelper('1.1.1.1',3306, 'alex', 'sb')
    场景--访问数据库

      

      函数式编程 和 面向对象 使用情景

        对于 C# 和 Java 程序员来说不存在这个问题,因为该两门语言只支持面向对象编程(不支持函数式编程)。而对于 Python 和 PHP 等语言却同时支持两种编程方式,且

    函数式编程能完成的操作,面向对象都可以实现;而面向对象的能完成的操作,函数式编程不行(函数式编程无法实现面向对象的封装功能)。所以,一般在Python开发中,全部

    使用面向对象 或 面向对象和函数式混合使用

      类和对象在内存中保存状况

       类以及类中的方法在内存中只有一份,而根据类创建的每一个对象都在内存中需要存一份

     

    类成员

       一、字段

          1.普通字段

          2.静态字段

       二、方法

          1.普通方法

          2.静态方法

          3.类方法

       三、属性(特性)

    一、字段  

      普通字段属于对象(保存在对象中,执行只能通过对象访问)

      静态字段属于类 (保存在类中,  执行可以通过对象访问 也可以通过类访问)

    class provice:
        country = "中国" #静态字段
        def __init__(self,name):
            self.name = name     #普通字段
            #self.country = "中国"
    print(provice.country)         #中国
    shanxi = provice("陕西")
    a = shanxi.name
    print(a)                      #陕西
    字段

      

      静态字段在内存中只保存一份

      普通字段在每个对象中都要保存一份

      应用场景: 通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段

    二、方法 

      普通方法,保存在类中,由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self

      静态方法,保存在类中,由调用;无默认参数;

      类方法,保存在类中,至少一个cls参数;执行类方法时,自动将调用该方法的复制给cls

    方法(一一对应)
    #普通方法
    #静态方法
    #类方法
    class foo:
        def a(self):       #普通方法
            print("aaaaaaaaaaaaa")
    
        @staticmethod         #静态方法
        def b():            #没有参数,可自己加
            print("111111111")
    
        @staticmethod           ##静态方法
        def c(a1,b1):
            print(a1,b1)
        @classmethod                #类方法
        def d(cls):                #参数为cls(class缩写),直接将类传入
            print("pppppppppppppppppp")
    obj = foo()
    obj.a()                    #aaaaaaaaaaaaa
    foo.b()                   #111111111
    foo.c(1,2)                #1 2
    foo.d()                   #pppppppppppppppppp
    方法

    相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。

    不同点:方法调用者不同、调用方法时自动传入的参数不同。

    三、属性(特性)

      1.属性的基本使用

      2.属性的两种定义方式

    1.属性的基本使用

    #属性(特性)
    class foo:
        @property
        def a(self):
            print("aaaaaaaaaaaaa")
            return 1111
        @a.setter
        def a(self,v):
            print(v)
            return 1111
        @a.deleter
        def a(self):
            print("cccccccccc")
            return 1111
    obj = foo()
    f = obj.a           #aaaaaaaaaaaaa
    print(f)             #1111
    obj.a = 345          #345
    del obj.a            #cccccccccc
    属性
    • 定义时,在普通方法的基础上添加 @property 装饰器
    • 定义时,属性仅有一个self参数
    • 调用时,无需括号

               方法:foo_obj.func()
               属性:foo_obj.prop

    注意:属性存在意义是:访问属性时可以制造出和访问字段完全相同的假象

            属性由方法变种而来,如果Python中没有属性,方法完全可以代替其功能。

    实例:对于主机列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示的指定获取从第start条到第end条的所有数据(即:limit start , end),这个分页的功能包括:

      根据用户请求的当前页和总数据条数计算出start 和 end

      根据start 和 end去数据库中请求数据 

    #平常方法
    li = []
    for i in range(1000):
        li.append(i)
    while True:
        p = input("请输入页码:")
        p = int(p)
        start = (p-1)*10
        end = p*10
        print(li[start:end])
    
    #属性方法
    class Pag:
        def __init__(self,currt_pag):
            self.pag = int(currt_pag)
            try:
                p = int(currt_pag)
            except Exception as e:
                p = 1
        @property
        def start(self):
            v1=(self.pag-1)*10
            return v1
        @property
        def end(self):
            v1=self.pag*10
            return v1
    
    li = []
    for i in range(1000):
        li.append(i)
    while True:
        p = input("请输入页码:")
        # start = (p-1)*10
        # end = p*10
        obj = Pag(p)
        print(li[obj.start:obj.end])
    属性应用

    Python的属性的功能是:属性内部进行一系列的逻辑计算,最终将计算结果返回。

    2.属性的两种定义方式

      装饰器 即:在方法上应用装饰器(在类的普通方法上应用@property装饰器)

      例上:属性应用

      静态字段 即:在类中定义值为property对象的静态字段(创建值为property对象的静态字段)

    #属性(特性)第二种写法
    class foo:
        def a(self):
            print("aaaaaaaaaaaaa")
            return 1111
        def b(self,v):
            print(v)
            return 1111
        def c(self):
            print("cccccccccc")
            return 1111
        per = property(fget=a,fset=b,fdel=c,doc=".......")#doc=" "可有可无,对per的说明
    
    obj = foo()
    f = obj.per          #自动调用第一个参数中定义的方法:get_bar          #aaaaaaaaaaaaa
    print(f)                                               #1111
    obj.per= 123345     # 自动调用第二个参数中定义的方法:set_bar方法,并将123345当作参数传入     #123345
    del obj.per          # 自动调用第三个参数中定义的方法:del_bar方法                 #cccccccccc
    属性第二种方法

    property的构造方法中有个四个参数

    1. 第一个参数是方法名,调用 对象.属性 时自动触发执行方法
    2. 第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法
    3. 第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法
    4. 第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息

     

  • 相关阅读:
    谈Delphi编程中“流”的应用 (一)
    Ihtmldocument2接口的使用
    TWebBrowser 异常 invalid floating point operation
    万一的 Delphi 博客 (注意 delphi的新功能)
    正则表达式应用(一)
    查询数据库所有表所有字段的某个值,生成更新代码 (VB)
    正则表达式应用(二)
    让程序支持脚本
    查探对方是否加你为好友
    常用的一些批处理,脚本功能(一)
  • 原文地址:https://www.cnblogs.com/lst1010/p/5895724.html
Copyright © 2011-2022 走看看