zoukankan      html  css  js  c++  java
  • Python学习---面向对象的学习[基础]

    面向对象

    面向对象的三大特性是指:封装、继承和多态。

    说明: Python可以函数式编程,也可以面向对象编程

    l 面向过程:根据业务逻辑从上到下写垒代码

    l 函数式 :将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可

    l 面向对象:对函数进行分类和封装,让开发“更快更好更强...”

    面向对象使用场景: 多个函数中,有相同的参数时,考虑面向对象编程【sql连接等】

    需要封装一部分内容的时候,就考虑用类解决

    函数和面向对象的区别:定义 + 执行的区别

    image

    类的创建以及self的含义:self代表调用该方法的执行对象

    class Bar:
        def foo(self, name, age, gender, content):
            print(self.school, self.haha, name, age, gender, content)
    z = Bar()
    z.school = 'peking'
    z.haha = 'hhh'
    print(z.school)
    z.foo('ftl', 123, 'male', 'hello world')

    构造方法

    构造方法__init__(self, args):  函数的初始化的时候自动执行

    class Bar:
        # 构造方法
        def __init__(self, name, age, gender, content):
            self.name = name
            self.age = age
            self.gender = gender
            self.content = content
            self.boold = 'O'                    # 初始化默认的参数
            print('__init__')                   # __init__
            print(name, age, gender, content, self.boold)   # hhh 23 male hello world
    z = Bar('hhh', 23, 'male', 'hello world')  # hhh 23 male hello world O 

    父类调用

    1. super的调用:super(子类函数名, 调用的self),  eg, super(Son, self),先认儿子,再找调用者

    2. Father.__init__(self):  由父类名直接调用,我们由对象调用方法的时候,Py会自动帮我们传递self参数,但是由Father类直接调用的时候,需要把调用对象z传递过去。

    class Father:
        def __init__(self):
             print('Father')
        def hello(self):
            print('Father:hello')
    class Son(Father):
       def __init__(self):   
          # super(Son, self).__init__()#  这里super(子类名,self)调用父类的init方法
          Father.__init__(self)      #  这里父类名.方法(self) 调用父类方法
    # 父类名调用的时候,缺少参数报错 __init__() missing 1 required positional argument: 'self'
            print('Son')
        def hello(self):
            print('Son:hello')
            super(Son, self).hello()      # 调用父类的方法
        def world(self):
            print('son:world')
    z = Son()
    z.hello()
    z.world()

     封装性

    将内容封装到某个地方,以后再去调用被封装在某处的内容。

    特 性:

    将内容封装到某处

    从某处调用被封装的内容

    class Bar:
        def foo(self, content):
            print(self.name, self.age, self.gender, content)
    z = Bar()
    z.name = 'ftl'
    z.age = 12
    z.gender = 'male'
    z.foo('hello world')      # ftl 12 male hello world

    继承性:

    子可以继承父的内容。将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。

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

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

    继承:先在子类自己的方法中查找,然后再去父类的方法查找

    class Father:
        def __init__(self):
             print('Father')
        def hello(self):
            print('Father:hello')
    class Son(Father):
        # def __init__(self):
        #     print('Son')    #  子类的构造方法没有覆盖父类,则xian执行父类的构造方法
        def __init__(self):   #  这里的子类覆盖掉了父类的init方法,所以打印子类自己的print
            print('Son')
        def world(self):
            print('son:world')
    z = Son()                 # Son
    z.hello()         #Father:hello
    z.world()                 # son:world

    多继承:

            a. 左侧优先

            b. 一条道走到黑

            c. 同一个根时,根最后执行

            d. self代表调用的函数对象,遇到self调用函数的时候,确定self是谁的对象,然后一定是回到原点开始往上找方法的

    class BaseRequest():
        pass
    class RequestHandler(BaseRequest):
        def server_forver(self):
            print('RequestHandler: server_forver')
            self.process_request()              # 回到起点开始网上找,结果:Minx    : process_request
    
        def process_request(self):
            print('RequestHandler: process_request')
    class Minx:
        def process_request(self):
            print('Minx          : process_request')
    
    class Son(Minx, RequestHandler):
        pass
    
    s = Son()
    s.process_request()                           # Minx          : process_request
    s.server_forver()                             # RequestHandler: server_forver

    多态性

    Python自带多态的特性,因为Python会自动判断你传入的参数是什么类型,不用特别声明

    def foo(args):
        print(args)
    foo("hello world")   # hello world
    foo(1234567)         # 1234567

    类的一个小程序:

      Python实例---游戏人生[类的学习]

    类的成员

    类的成员:

    字段: 2种

    方法:   3种

    属性: 1种

    特殊成员:

    1种

    image

    普通字段属于对象,只能通过对象访问

    静态字段属于类,可以通过对象,也可以通过类

    class province:
        country = 'China'                   #创建全局变量country, 她是类的对象,创建类的时候生成
        # def __init__(self, name, country='CHINA'): # 这里的name是对象的字段,类似Java中的属性
        def __init__(self, name):
            self.name = name
            print(self.name, province.country)
    
    henan = province('henan')
    print(province.country)   # 可以通过类调用,也可以通过类调用
    print(henan.country)      # 可以通过对象调用,也可以通过类调用
    # print(province.name)    # 不能通过对象查找类  type object 'province' has no attribute 'name'

    方法:方法保存在类中,可以通过类查找,也可以通过对象调用,但是前提是都要先创建一个类的对象

    class Province:
        country = 'China'                  # 创建全局变量country, 她是类的对象,创建类的时候生成
      # def __init__(self, name, country='CHINA'):   # 这里的name是对象的字段,类似Java中的属性
        def __init__(self, name):
            self.name = name
        def fun(self):
            print(self.name, Province.country)
    henan = Province('henan')
    henan.fun()           #推荐使用
    # Province.fun()      #需要传递对象过去  fun() missing 1 required positional argument: 'self'
    Province.fun(henan)

    静态方法:@ staticmethod装饰器来完成静态方法,此时可以省略self参数,直接由类调用

    class Province:
        country = 'China'                  # 创建全局变量country, 她是类的对象,创建类的时候生成
     # def __init__(self, name, country='CHINA'):   # 这里的name是对象的字段,类似Java中的属性
        def __init__(self, name):
            self.name = name
        @staticmethod
        def fun(city, house):          # 可以不用传递self参数
            print(Province.country, city, house)
    henan = Province('henan')
    henan.fun('HuNan', 'Chaoyang')
    Province.fun('HuNan', 'Chaoyang')   # 推荐使用,直接用类调用,此时的self参数可以不用传递

    类方法:由类直接调用,必须传递一个形式参数,此时python会自动帮我们传递一个类名过去,所以一般命名为cls

    class Province:
        @classmethod
        def class_method(cls):          #必须传递一个形式参数,python自动传递类名过去
            # cls 是类名,不依赖对象
            print('class_method:', cls) # 此时python会自动帮我们传递一个类名过去
    Province.class_method()             # 由类直接调用,此时python会自动帮我们传递一个类名过去
    
    # 结果: class_method: <class '__main__.Province'>

    属性(@property):定义的时候像方法,而且也有返回值, 使用的时候像字段

    class Province:
        @property
        def fun(self):
            print('hello world')
            return 'ok'
    obj = Province()
    ok = obj.fun
    print(ok)                # hello world

    属性表达一:(@fun.setter/@fun.deleter):仅仅是对应关系

    class Province:
        @property               # 用于执行obj.fun 接收值
        def fun(self):
            print('hello world')
            return 'ok'
        @fun.setter              # 用于obj.fun = 123 ,重新赋值
        def fun(self, val):
            print(val)
    
        @fun.deleter             # 仅仅是一个对应关系,不涉及真正的删除
        def fun(self):
            print('delete')
    obj = Province()
    ok = obj.fun
    print(ok)
    obj.fun = 'hello Python'      # 查找对应的关系
    del obj.fun                   # 不会真正的执行删除的操作,仅仅只是一个对应关系

    属性表达二:(property函数):仅仅是对应关系

    class Page:
        def f1(self):
            return 'hhh'
        def f2(self, val):
            print(val)
        def f3(self):
            print('del')
        pp = property(fget=f1, fset=f2, fdel=f3, doc='Property用法二')
    
    p = Page()
    # ret = p.f1()
    # print(ret)
    
    print(p.pp)   #  hhh
    p.pp='hello'  #  hello
    del p.pp      #  del

    利用属性实现分页

    class Page:
        def __init__(self, page):
            try:
                page = int(page)
            except Exception as e:
                page = 1
            self.page = page
        @property
        def start(self):
            page = (self.page - 1) * 10
            return  page
        @property
        def end(self):
            page = self.page * 10
            return  page
    li = []
    for i in range(100):
        li.append(i)
    while True:
        page = input("请输入页码:")
        obj = Page(page)
        print(li[obj.start:obj.end])

    成员修饰符

    公有成员 默认公有

    私有成员   __小写字段名   不能直接访问,只能间接访问

    继承也不能访问父类的私有字段,只能访问共有字段

    class Foo:
        __school = 'xupt'             # 静态私有字段,外部无法直接访问
        def __init__(self, name, age):
            self.name = name
            # self.age = age
            self.__age = age          # 私有变量,外部无法直接访问
        def show(self):
            print(self.__age, self.__school)         # 从内部简介访问
        @staticmethod
        def stat():
            print(Foo.__school)
        def __private(self):
            print('privatemethod')
        def f(self):
            self.__private()
    obj = Foo('hhh', 12)
    obj.show()        # 12 xupt
    Foo.stat()        # xupt
    obj.f()           # privatemethod

    子类不能访问父类的私有变量

    class F:
        def __init__(self):
            self.f_name = 'Father'
            # self.__fage = 54     # 父类的私有变量
    
    class S(F):
        def __init__(self, name, age):
            F.__init__(self)
            self.name = name
            self.__age = age
    
        def show(self):
            print(self.__age, self.name)
    
        def showFather(self):
            print(self.f_name)
            print(self.__fage)   # 报错,父类的私有变量
    obj = S('hhh', 23)
    obj.show()           # 23 hhh
    obj.showFather()     # Father

    特殊成员

        __init__     类()自动执行

        __del__ 析构方法,对象被销毁时自动触发,Py自动执行

        __call__     对象()  类()() 自动执行

        __int__      int(对象)

        __str__      str()    

        __add__

        __dict__     # 讲对象中封装的所有内容通过字典的形式返回

        __getitem__  # 切片(slice类型)或者索引

        __setitem__

        __delitem__    

        __iter__

                    # 如果类中有 __iter__ 方法,对象=》可迭代对象

                    # 对象.__iter__() 的返回值: 迭代器

                    # for 循环,迭代器,next

                    # for 循环,可迭代对象,对象.__iter__(),迭代器,next

                    # 1、执行li对象的类F类中的 __iter__方法,并获取其返回值

                    # 2、循环上一步中返回的对象

    __call__     对象()  类()() 自动执行

    class F:
        def __init__(self, name, age):
            self.name = name
            self.age = age
            print(self.name, self.age)
        def __call__(self, *args, **kwargs):
            print('Call')
    
    obj = F('hhh', 23)
    obj()                  # 等价于   F('hhh', 23)()  对象也可以添加()来执行

    __int__/__str__/__add__

    class F:
        def __init__(self, name):
            self.name = name
        def __int__(self):
            return 1234
        def __str__(self):
            return 'Father'
        def __add__(self, other):         # 对象的重组
            # self= f('hello')
            # other = ff('world')
            return self.name + other.name
    f = F('hello')
    ff = F('world')
    # print(f+ff)   # 没有add方法,报错, unsupported operand type(s) for +: 'F' and 'F'
    print(f+ff)     # helloworld, 2个对象相加时候,会执行第一个对象的__add方法,并且将第二个对象作为参数传递过去
    print(int(f))   # 1234,   对象转换为int型
    print(str(f))   # Father, 对象转换为str型

    __dict__     # 将对象/类中封装的所有内容通过字典的形式返回

    class F:
        # hello我让ld
        def __init__(self, name):
            self.name = name
        def show(self):
            print(self.__dict__)
    f = F('hello')
    f.show()            # 打印对象里面的所有成员
    print(F.__dict__)   # 打印类里面的所有成员

    __getitem__/__setitem__/__delitem__的使用

    # 问: li本身也是一个对象,为什么可以直接用下标来取值呢?
    # 答; 因为list里面有__getitem__, __setitem__, __delitem__
    li = ['hello', 'world', '2017']
    print(li[1])
    # print(li[1:4:2])
    li[1] = 'ftl'
    del li[1]
    
    # 函数利用使用__ getitem__
    lass F:
        def __init__(self, name):
            self.name = name
        def __getitem__(self, item):
            if type(item) == 'slice':
                print('这里采用切片调用',item.start, item.stop, item.step)
            else:
                print('这里采用索引调用')
            return item
        def __setitem__(self, key, value):
            print(key, value)
        def __delitem__(self, key):
            print(key)
    obj = F('hello')
    print(obj['hello'])
    obj['hello']='world'
    del obj['hello']

    __iter__: 迭代器的原理

    class F:
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __iter__(self):                # 代表F是一个可迭代对象
            return iter([1, 2, 3, 4, 5])   # 返回一个迭代器
    
    f = F('hhh', 23)
    for i in f:                            # for循环循环next()迭代打印
        print(i)


    【学习参考】http://www.cnblogs.com/wupeiqi/p/4493506.html

  • 相关阅读:
    读写配置文件app.config
    UML类图
    我见到James Rumbaugh了!
    获取数据库中的所有表
    通过DataTable获得表的主键
    用例的本质
    用例图
    使用SQLDMO中“接口SQLDMO.Namelist 的 QueryInterface 失败”异常的解决方法
    类如何与界面绑定
    C#使用指针
  • 原文地址:https://www.cnblogs.com/ftl1012/p/9383598.html
Copyright © 2011-2022 走看看