• python18-day7


    什么时候使用面向对象? 当某些函数具有相同参数时,可以使用面向对象的方式,讲参数值一次的封装到对象,以后去对象中取值即可
     

    面向对象的特点

    封装,继承,多态   #多态(意义不大,java等强类型,应用多)
     

    类和对象

    一 创建类
    class 类名:
        def 方法名(self,***):
            pass
    二 创建对象
        对象=类名()
     
    三 通过对象执行方法
    对象.方法名(123)
     
     
    self是python会自动传值的参数
    构造方法:   __init__()   #自动被执行,   ()中可填参数
     

     

    类定义

    1. #类通过函数改变
    2. class Person:
    3. def __init__(self,name,age,money):
    4. self.name=name
    5. self.age=age
    6. self.money=money
    7. def shopping(self):
    8. self.money=self.money -200
    9. print(self.money)
    10. long=Person("龙",18,400)
    11. hu=Person("虎",18,300)
    12. long.shopping()
    13. hu.shopping()
    14. # 200
    15. # 100

    计数器

    1. class Foo:
    2. count=0
    3. def __init__(self,name):
    4. Foo.count+=1            #写Foo.count Foo代表类
    5. self.name=name
    6. obj1=Foo("egon1")
    7. obj2=Foo("egon2")
    8. # print(Foo.count)
    9. # print(obj2.count)
    10. class Student:
    11. tag = "tag值" #灵活性,可增加参数
    12. def __init__(self,ID,name,age):
    13. self.id=ID
    14. self.name=name
    15. self.age=age
    16. def walk(self):
    17. print("%s is waokking"%self.name)
    18. s1=Student(1,"egon",18)
    19. s2=Student(2,"alex",1000)
    20. s1.walk()
    21. s2.walk()
    22. print(s1.id,s1.name,s1.age,s1.tag)
    23. print("用户数量",Foo.count)
    24. # egon is waokking
    25. # alex is waokking
    26. # 1 egon 18 tag值
    27. # 用户数量 2
     
     
     

       类的传参可以是另一个类

    1. class c1:
    2. def __init__(self,name,obj):
    3. self.name = name
    4. self.obj=obj
    5. class c2:
    6. def __init__(self,name,age):
    7. self.name = name
    8. self.age=age
    9. def show(self):
    10. print(self.age)
    11. c2_obj=c2("aa",11) #c2("aa", 11).show() 这样也行
    12. c2_obj.show() #显示show函数值
    13. #11
    14. print(c2_obj.name) #也可以调用变量,显示变量要加print
    15. #aa
    16. c1_obj=c1("alex",c2_obj) #c1_obj的参数可以是c2_obj函数
    17. print(c1_obj.obj.name) #c1_obj.obj.name =c2_obj.name
    18. #aa
     
     

    继承

    继承是一种创建类的方式
     
    F2继承F1所有数据
    1. class F1:
    2. def show(self):
    3. print("show")
    4. class F2(F1):
    5. def bar(self):
    6. print("bar your right")
    7. obj = F2()
    8. obj.bar()
    9. #bar your right
     
     

    F2继承F1

    F2继承了F1的函数 如果F2和F1中有同名函数执行F2函数(子类优先)
    1. class F1: #父类,基类
    2. def show(self):
    3. print("show")
    4. def foo(self):
    5. print(self.name)
    6. class F2(F1): #子类,派生类
    7. def __init__(self,name):
    8. self.name = name
    9. def bar(self):
    10. print("bar your right")
    11. def show(self):
    12. print("F2,show")
    13. obj = F2("alex")
    14. obj.foo()

    父类不变,子类改变

     
    1. class Animal:
    2. def __init__(self,name,age,sex):
    3. self.name=name
    4. self.age=age
    5. self.sex=sex
    6. def eat(self):
    7. print("%s eat"%self.name)
    8. def takl(self):
    9. print("%s say"%self.name)
    10. class People(Animal):
    11. def __init__(self,name,age,sex,education):
    12. Animal.__init__(self,name,age,sex) #这是调用父类初始化
    13. self.education=education
    14. peo1=People("alex",18,"male","小学")
    15. print(peo1.__dict__) #不加__dict__是内存地址
     
     
    1. class Animal:
    2. def __init__(self,name,age,sex):
    3. self.name=name
    4. self.age=age
    5. self.sex=sex
    6. def eat(self):
    7. print("eating")
    8. def talk(self):
    9. print("="*8)
    10. print("%s 在干嘛" %self.name)
    11. class People(Animal):
    12. def __init__(self,name,age,sex,education):
    13. Animal.__init__(self,name,age,sex)
    14. self.education=education
    15. def talk(self):
    16. Animal.talk(self)
    17. print("%s say hello %s"%(self.name,self.education))
    18. class Pig(Animal):
    19. def __init__(self,name,age,sex):
    20. Animal.__init__(self,name,age,sex)
    21. def talk(self):
    22. Animal.talk(self) #执行Peple中的tailk子类优先
    23. print("%s 哼哼哼"%self.name)
    24. class dig(Animal):
    25. def __init__(self,name,age,sex):
    26. Animal.__init__(self,name,age,sex)
    27. def talk(self):
    28. Animal.talk(self) #执行Peple中的tailk子类优先
    29. print("%s 汪汪汪汪"%self.name)
    30. peo1=People("alex",18,"male","小学文凭")
    31. pig=Pig("wupeiqi",20,"female")
    32. dig=dig("haha",20,"male")
    33. #print(peo1.education)
    34. peo1.talk()
    35. pig.talk()
    36. dig.talk()

    继承组合调用

    1. #组合也可以解决代码冗余问题,但是组合反映是一种什么有什么的关系
    2. class People:
    3. def __init__(self,name,age,sex):
    4. self.name=name
    5. self.age=age
    6. self.sex=sex
    7. # class Teacher(People):
    8. # def __init__(self,name,age,sex,salary):
    9. # People.__init__(self,name,age,sex)
    10. # self.salary=salary
    11. #
    12. # class Student(People):
    13. # pass
    14. class Date:
    15. def __init__(self,year,mon,day):
    16. self.year=year
    17. self.mon=mon
    18. self.day=day
    19. def tell(self):
    20. print('%s-%s-%s' %(self.year,self.mon,self.day))
    21. class Teacher(People):
    22. def __init__(self,name,age,sex,salary,year,mon,day):
    23. self.name=name
    24. self.age=age
    25. self.sex=sex
    26. self.salary=salary
    27. self.birth=Date(year,mon,day) #组合调用
    28. class Student(People):
    29. def __init__(self,name,age,sex,year,mon,day):
    30. self.name=name
    31. self.age=age
    32. self.sex=sex
    33. self.birth=Date(year,mon,day)
    34. t=Teacher('egon',18,'male',3000,1995,12,31)
    35. t.birth.tell()
     
     
     

    类查询对象顺序

    1. #先查C1的所有父类,有f2,匹配退出,如果没有,再查C1,有f2,匹配退出,都没有报错
    2. class C1:
    3. def f2(self):
    4. print("C1中的f2")
    5. class C2:
    6. def f2(self):
    7. print("C2中的f2")
    8. class C3(C1,C2):
    9. def f3(self):
    10. print("C3中的f3")
    11. obj=C3()
    12. obj.f2()
     

    2种类

    经典类:     
    深度优先 (python2 ,特定是N条父类连接相同父父类, 第一条生效)
     
    新式类:     
    广度优先 (python2+python3 特定是N条父类连接相同父父类, 最后一条生效)
    #python2中用新式类父父类要加object    例如class C0(object):

    多继承

    1. #新式类, 特定是N条父类连接相同父父类, 最后一条生效
    2. #查询顺序 C3(自己)-C2-C1-C5-C4-C0
    3.  
    4. class C0:
    5. def test(self):
    6. print("C0")
    7. class C1(C0):
    8. # def test(self):
    9. # print("C1")
    10. pass
    11. class C2(C1):
    12. # def test(self):
    13. # print("C2")
    14. pass
    15. class C4(C0):
    16. # def test(self):
    17. # print("C4")
    18. pass
    19. class C5(C4):
    20. # def test(self):
    21. # print("C5")
    22. pass
    23. class C3(C2,C5):
    24. # def test(self):
    25. # print("C3")
    26. pass
    27. obj=C3()
    28. obj.test()
    29. print(C3.mro())     
    30. #mro显示执行过程(最后一位提供返回值) 执行C3的test函数,看执行过程

    31. #[<class '__main__.C3'>, <class '__main__.C2'>, <class '__main__.C1'>, <class '__main__.C5'>, <class '__main__.C4'>, <class '__main__.C0'>, <class 'object'>] 
    32.  
     
    super调用方法
    1.  
    2. class Animal:
    3. home="oldboy"
    4. def __init__(self,name,age,sex):
    5. self.name=name
    6. self.age=age
    7. self.sex=sex
    8. def eat(self):
    9. print("%s eat"%self.name)
    10. def takl(self):
    11. print("%s say"%self.name)
    12. class People(Animal):
    13. def __init__(self,name,age,sex,education):
    14. #Animal.__init__(self,name,age,sex) #这是调用父类初始化
    15. super().__init__(name,age,sex,) #这是调用父类初始化的另一种方法
    16. #super(People,self).__init__(name,age,sex,) #python2写法
    17. #print(super().home) #使用super.可直接调用父类的(对象,函数,变量) = print(Animal.home)
    18. self.education=education
    19. peo1=People("alex",18,"male","小学")
    20. print(peo1.__dict__) #不加__dict__是内存地址
    21. #{'name': 'alex', 'age': 18, 'sex': 'male', 'education': '小学'}
    22. peo1.eat()
    23. #alex eat
    24. print(People.mro()) #查新式类最后调用
    25. #[<class '__main__.People'>, <class '__main__.Animal'>, <class 'object'>]
    26. #super的另一种含义是直接调用最后一个父类
    27. class A:
    28. def test(self):
    29. super().test() #此时的super是从<class '__main__.A'>后 继续调用mro继续查看,继续则是C(B),得到B父类的test
    30. class B:
    31. def test(self):
    32. print('B')
    33. class C(A,B):
    34. pass
    35. # a=A()
    36. # a.test()
    37. print(C.mro())
    38. c=C()
    39. c.test()
    40. #[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
    41. #B
    42.  
    43.  
     

    抽象类

    #一个抽象类有多个子类,因而多态的概念依赖于继承
    1. #主要作用:函数规范 , 只要是调用这个父级的read函数 子级也必须用read
    2. import abc #利用abc模块实现抽象类
    3. class All_file(metaclass=abc.ABCMeta):
    4. all_type='file'
    5. @abc.abstractmethod #定义抽象方法,无需实现功能
    6. def read(self):
    7. '子类必须定义读功能'
    8. pass
    9. #定义其他抽象类就继续仿照read写
    10. class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法
    11. def read(self):
    12. print('文本数据的读取方法')
    13. class Process(All_file): #子类继承抽象类,但是必须定义read和write方法
    14. def read(self):
    15. print('进程数据的读取方法')
    16. guolm=Txt()
    17. qiqi=Process()
    18. #规范了必须用read函数, 如果把guolm的类中read函数名改变,就会报错
    19. #Can't instantiate abstract class Txt with abstract methods read
    20. guolm.read()
    21. qiqi.read()
    22. print(guolm.all_type)
    23. print(qiqi.all_type)
    24. # 文本数据的读取方法
    25. # 进程数据的读取方法
    26. # file
    27. # file
     
     

    多态和多态性

    多态

    多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承
    #多态:调用父类有共同的参数,返回子类又增加各自子类的变化

    多态性

    多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同功能的函数。
    1. import abc
    2. class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
    3. @abc.abstractmethod #抽象
    4. def talk(self):
    5. pass
    6. class People(Animal): #动物的形态之一:人
    7. def talk(self):
    8. print('say hello')
    9. class Dog(Animal): #动物的形态之二:狗
    10. def talk(self):
    11. print('say wangwang')
    12. class Pig(Animal): #动物的形态之三:猪
    13. def talk(self):
    14. print('say aoao')
    15. People=People()
    16. People.talk()
    17. Dog=Dog()
    18. Dog.talk()
    19. Pig=Pig()
    20. Pig.talk()
    21. # say hello
    22. # say wangwang
    23. # say aoao
     

     

     
     

    封装

     
    1 类把某些属性和方法隐藏起来(或者说定义成私有的,)只在类的内部使用,外部无法访问,或者留下少量接口(函数)供外部访问
    隐藏封装
    在内部使用__ 会调用值 在外部不成立
    1. #类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果。
    2. #这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。
    3. #这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。
    4.  
    5. #在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。
    6. class People:
    7. def __init__(self,name,age,sex):
    8. self.__name=name
    9. self.__age=age
    10. self.__sex=sex
    11. def tell_info(self):
    12. #print("人的名字是:%s, 人的性别是:%s, 人的年龄是:%s "%(self.__name,self.__age,self.__sex))
    13. return "人的名字是:%s,人的性别是:%s,人的年龄是:%s "%(self.__name,self.__age,self.__sex)
    14. p=People("alex",18,"male")
    15. print(p.tell_info()) #显示结果
    16. #人的名字是:alex,人的性别是:18,人的年龄是:male
    17. print(p.__dict__) #显示p的字典状态
    18. #{'_People__name': 'alex', '_People__age': 18, '_People__sex': 'male'}

    父子类函数同名,调用父类函数

    1.  
    2. class Parent:
    3.    __x=1
    4. def foo(self):
    5. print("from parent.foo")
    6. self.__bar() #值是完整文件名_parent__foo__bar, 相当于指定调用
    7. def __bar(self):
    8. print("from parent.bar")
    9. class Sub(Parent):
    10. def bar(self):
    11. print("from Sub.bar")
    12. s=Sub()
    13. s.foo()
    14. #from parent.foo #from parent.bar
    15. print(Parent.__dict__)      #看Parent的所以含义
      #{'__module__': '__main__', '_Parent__x': 1, 'foo': <function Parent.foo at 0x101448598>, '_Parent__bar': <function Parent.__bar at 0x1014486a8>, '__dict__': <attribute '__dict__' of 'Parent' objects>, '__weakref__': <attribute '__weakref__' of 'Parent' objects>, '__doc__': None}
     

    super

    根据mro查找
    父类改变 子类只需要改变类调用 不需要改子类函数
    1. class Foo1: #父类名改变
    2. def test(self):
    3. print("from foo.test")
    4. class Bar(Foo1): #子类名改变,不需要改子类的test函数
    5. def test(self):
    6. #Foo.test(self) 相对于如下
    7. super(Bar,self).test() #使用super,父类改变 子类只需要改变类调用 不需要子类改函数
    8. print("bar222")
    9. a=Bar()
    10. a.test()
    11. #from foo.test #bar222
     

    内置装饰器

    内置的装饰器有三个:staticmethod(静态类方法) classmethod, 类方法  property
     
    staticmethod,(静态类方法)
    基本上跟一个全局函数相同,一般来说用的很少
     
    classmethod
    • classmethod 是一个函数修饰符,它表示接下来的是一个类方法,而对于平常我们见到的则叫做实例方法。 类方法的第一个参数cls,而实例方法的第一个参数是self,表示该类的一个实例。 
    • 普通对象方法至少需要一个self参数,代表类对象实例
    • 类方法有类变量cls传入,从而可以用cls做一些相关的处理。并且有子类继承时,调用该类方法时,传入的类变量
    1. staticmethod+classmethod实例
    2. setting.py文件
      1. host="192.168.1.1"
      2. port=3004
       
    3. import setting
    4. import uuid
    5. class Mysql:
    6. def __init__(self,host,port):
    7. self.host=host
    8. self.port=port
    9. self.id=self.create_id()
    10. @classmethod      #绑定方法,绑定给class类
    11. def from_conf(cls): #cls=Mysql()
    12. return cls(setting.host)
    13.                              #setting是模块,setting.host中host是模块变量
    14. def func(self): #绑定给object对象
    15. pass
    16. @staticmethod         #非绑定方法,变成普通函数,不绑定给类或对象
    17. def create_id():
    18. return str(uuid.uuid1())
    19. conn_one=Mysql("1.1.1.1",3306)
    20. conn_tow=Mysql.from_conf()
    21. print(conn_one.host)
    22. print(conn_tow.host)
    23. #1.1.1.1
    24. #192.168.1.1
    25. print(Mysql.from_conf) #这是显示绑定类
    26. #<bound method Mysql.from_conf of <class '__main__.Mysql'>>
    27. print(Mysql.func) #这是显示绑定对象
    28. #<function Mysql.func at 0x101c287b8>
    29. print(conn_one.id) #这是显示非绑定方法
    30. #5da84770-81dc-11e7-9569-48bf6be5ec1a
     

    property

    计算bmi(健康状态)
    1. #定义好数值,外部传参 可修改数值
    2. class People:
    3. def __init__(self,name,weight,height):
    4. self.name=name
    5. self.weight=weight
    6. self.height=height
    7. @property #类似装饰器,装饰下边
    8. def bmi(self):
    9. return self.weight / (self.height ** 2)
    10. p=People("egon",75,1.80)
    11. p.height=1.84        #外部可改传参
    12. print(p.bmi)
    13. #22.152646502835537
     

    封装之更改和删除

    1. class People:
    2. def __init__(self,name,permmission=False):      #permmission=False 定义默认值 用于增加权限  
    3. self.name=name
    4. self.permmission=permmission
    5. @property                                        #继承
    6. def name(self):
    7. return self.__name
    8. @name.setter    #装饰器增加增加功能
    9. def name(self,value):
    10. if not isinstance(value,str):
    11. raise TypeError("名字必须是字符串类型")
    12. self.__name=value
    13. @name.deleter    #装饰器增加删除功能
    14. def name(self):
    15. if not self.permmission:     #permminsion值为False   
    16. #这样写permmission值必须为True 加not为False, 而设置是permminsion值就是False
    17. raise PermissionError("不允许的操作")
    18. del self.__name
    19. p=People("egon")
    20. p.permmission=True
    21. del p.name
    22. 另一种方法 效果相同
      1. class People:
      2. def __init__(self,name,permmission=False):
      3. self.name=name
      4. self.permmission=permmission
      5. def get_name(self):
      6. return self.__name
      7. def set_name(self,value):
      8. if not isinstance(value,str):
      9. raise TypeError("名字必须是字符串类型")
      10. self.__name=value
      11. def del_name(self):
      12. if not self.permmission:
      13. raise PermissionError("不允许的操作")
      14. del self.__name
      15. name=property(get_name,set_name,del_name)
      16. p=People("egon")
       
    23.  
     
     
    设计模式之单例模式(23,goF设计模式)
    单例模式
        用来创建单个实例
     
     
    练习:
    1 对象调用class 显示调用次数
    1. #Foo是类
    2. #self是对象自己
    3. class Foo:
    4. count=0
    5. def __init__(self,x,y,z):
    6. self.x=x
    7. self.y=y
    8. self.z=z
    9. def aa(self):
    10. Foo.count+=1
    11. return Foo.count
    12. obj1=Foo("guolm",18,"linux")
    13. obj2=Foo("wy",28,"linux")
    14. obj3=Foo("haha",38,"yw")
    15. print(obj1.aa())
    16. print(obj2.aa())
    17. print(obj3.aa())
    18. print(obj3.aa())
    19. # 1
    20. # 2
    21. # 3
    22. # 4
  • 相关阅读:
    jquery的ztree操作
    原创-使用pywinauto和swapy-ob-0.4.3进行dotnet的winform程序控制(二)
    原创-使用pywinauto进行dotnet的winform程序控制(一)
    javascript“命名空间”的费曼输出[原创]
    IIS7上传4M文件以上文件出现“Post大小超出允许的限制”错误解决方法
    OpenProj打开不了或者提示”Failed to load Java VM Library”的错误的解决方案
    项目管理中,开始到完成、完成到开始、开始到开始、和完成到完成的关系图解
    我的项目管理之干系人分析在单位项目中的运用
    关于学习js的Promise的心得体会
    vue.js与后台模板引擎“双花括号”冲突时的解决办法
  • 原文地址:https://www.cnblogs.com/Gavinkwok/p/7387998.html
Copyright © 2020-2023  润新知