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,\n人的性别是:%s,\n人的年龄是:%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

转载于:https://www.cnblogs.com/Gavinkwok/p/7387998.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值