pythonx1_面向对象

面向对象

基础

===

  1. oop

    面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
    Python类提供了面向对象编程的所有标准功能:类继承机制允许多个基类,派生类可以重写其基类或类的任何方法,并且方法可以调用具有相同名称的基类的方法。对象可以包含任意数量和种类的数据。与模块一样,类也具有Python的动态特性:它们是在运行时创建的,并且可以在创建后进一步修改。

  2. 定义类

        class Employee:
        '所有员工的基类'
        # empCount 变量是一个类变量,它的值将在这个类的所有实例之间共享。你可以在内部类或外部类使用 Employee.empCount 访问。
        empCount = 0
    
        # 方法__init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法
        def __init__(self, name, salary):
            self.name = name
            self.salary = salary
            Employee.empCount += 1
    
        # self 代表类的实例,self 在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。
        def displayCount(self):
            print ("Total Employee %d" % Employee.empCount)
            print (self.__class__)
    
        def displayEmployee(self):
            print("Name : ", self.name, ", Salary: ", self.salary)
        ee1= Employee('NICK',100000)
        ee2= Employee('ROSE',100000)
        
        ee1.displayCount()
        ee2.displayEmployee()
    

    类属性使用 类名.属性名 的方式去访问,对象也可以访问。但是如果对象修改,则只对当前对象适用(因为这是其实是增加对象属性)

  3. 动态为对象添加、删除属性

    只会影响到当前操作的对象

    ee1= Employee('NICK',100000)
    ee2= Employee('ROSE',888888)
    
    ee1.age=22
    print(vars(ee1))
    # del ee1.name
    print(vars(ee1))
    ee1.displayEmployee()
    
    # print ee2.age   #error
    
    print (hasattr(ee1, 'age') )   # 如果存在 'age' 属性返回 True。
    print (getattr(ee1, 'age') )   # 返回 'age' 属性的值
    setattr(ee2, 'age', 8) # 添加属性 'age' 值为 8
    print(ee2.age)
    delattr(ee1, 'age')  # 删除属性 'age'
  1. 析构函数
        def __del__(self):
            class_name = self.__class__.__name__
            print(class_name, "销毁")
            
    >当程序执行完毕后会调用析构函数释放对象,或者动态删除对象也会调用
    
        del ee1
        
        但是
        
        ee4=ee1
        
        del ee1 #这时不会析构对象,因为ee4还在应用对象
        
为什么下面会输出两次

    class A(object):              
        __scope='a scope'         
        def __init__(self, a):    
            self.a = a            
            print('init A...')    
                                  
                                  
        def __del__(self):        
            print('del')          
                                  
    a=A(12)                       
                                  
    a.__del__()   #这叫魔法语句                  
                                  
    print(id(a))                  
    print(id(a))                  

当执行a.del() 时虽然调用一次析构函数,但是没有真正删除对象,后面系统真删除对象时又调用了一次,可以通过下面测试

    a=A(12)                       
                                  
    a.__del__()                   
                                  
    print(id(a))                  
    
当执行del a后   
    
    print(id(a))  #error
  1. 内置属性
       print (Employee.__dict__)
       print (Employee.__doc__)
       # 类的所有父类构成元素(包含了一个由所有父类组成的元组)
       print (Employee.__bases__)
       print (Employee.__name__)
       ee1=Employee('NICK',200)
       print(isinstance(ee1,Employee))
       print(isinstance(ee1,object))
         
        ee1= Employee('NICK',100000)
        ee3= Employee('NICK',100000)
        ee1 is ee3 False
        ee1 == ee3 False

高级

===

  1. 继承
类的继承

1:在继承中基类的构造(\__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。

2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别在于类中调用普通函数时并不需要带上self参数

3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
    
```
    class Boss(Employee):
        def __init__(self,name,salary,jiangjin):
            super(Boss, self).__init__(name, salary)
            self.jiangjin = jiangjin
    
    
        def displayEmployee(self):
            print("Name : ", self.name, ", Salary: ", self.salary,'other jiangjin:',self.jiangjin)
        def __str__(self):
                pass
```
>python没有重载,因为函数名知识指向内存地址的变量。
  1. 多重继承

    #-*- coding:UTF-8 -*-
    
    # 多重继承
    
    class A(object):
        __scope='a scope'
        def __init__(self, a):
            print('init A...')
            self.a = a
        def show(self):
            print('i am A')
    
    class B(A):
        def __init__(self, a):
            super(B, self).__init__(a)
            print( 'init B...')
        def show(self):
            super(B,self).show()
            print(' and i am B too')
    
    class C(A):
        def __init__(self, a):
            super(C, self).__init__(a)
            print('init C...')
    
        def show(self):
            super(C, self).show()
            print(' and i am C too too')
    
    class D(B, C):
        def __init__(self, a):
            super(D, self).__init__(a)
            print('init D...')
        def show(self):
            super(D, self).show()
            print(' and i am D too too...')
    
    d=D(12)
    # print B.scope
    d.show()
    
    
    #d多重继承时为了从多个类中提取多个方法
    
    # 查看对象信息
    
    # print(isinstance(d,D))
    # print(isinstance(d,A))
    #
    # print(type(d))
    # print(dir(d))
    

    查看类的继承关系图,在类名上点右键选Diagrams 选show Diagrams

  2. 多重继承参数传递

    因为多重继承构造函数的执行顺序是A-C-B-D,所以D接受4个参数给父类B,B要接受4个参数、自己消化两个,然后B传给父类C,

     class A(object):
         __scope='a scope'
         def __init__(self, a):
             self.a = a
             print('init A...')
     
     class B(A):
         def __init__(self, a,b1,b2,c1,c2):
     
             super(B, self).__init__(a,c1,c2)
             self.b1=b1
             self.b2=b2
             print('init B...')
     
     class C(A):
         def __init__(self, a,c1,c2):
     
             super(C, self).__init__(a)
             self.c1=c1
             self.c2=c2
             print('init C...')
     
     class D(B, C):
         def __init__(self, a,d1,d2,d3,d4):
     
             super(D, self).__init__(a,d1,d2,d3,d4)
             print('init D...')
     
     
     d=D('a','bb','bbb','cc','ccc')
     
     
     print(vars(d))
    
  3. 你真的理解Python中MRO算法吗?

    MRO(Method Resolution Order):方法解析顺序。
    Python语言包含了很多优秀的特性,其中多重继承就是其中之一,但是多重继承会引发很多问题,比如二义性,Python中一切皆引用,这使得他不会像C++一样使用虚基类处理基类对象重复的问题,但是如果父类存在同名函数的时候还是会产生二义性,Python中处理这种问题的方法就是MRO。

    class A(object):
        __scope='a scope'
        def __init__(self, a):
            self.a = a
            print('init A...')
    
    class B(object):
        def __init__(self,a):
            self.a = a
            print('init B...')
    
    class C(A):
        def __init__(self, a):
    
            super().__init__(a)
            print('init C...')
    
    class D(B):
        def __init__(self, a):
            super().__init__(a)
            print('init D...')
    class E(C,D):
        def __init__(self, a):
    
            super().__init__(a)
    
    
            print('init E...')
    
    e=E(1)
    
    print(E.mro())
    
    
上面代码发现D B的构造方法没有被调用,因为对象属性没有做任何修改

    """
        作者:詹亮   日期:2019/7/26 4:52 PM
    """
    class A(object):
        __scope='a scope'
        def __init__(self, a,b):
            self.a = a
            super(A, self).__init__(a,b)
            print('init A...')
    
    class B(object):
        def __init__(self,a):
            self.a = a
            print('init B...')
    
    class C(A):
        def __init__(self, a,b):
    
            super().__init__(a,b)
    
            print('init C...')
    
    class D(B):
        def __init__(self, a,b):
            super().__init__(a)
            self.b=b
            print('init D...')
    
        def show(self):
            print('i am d')
    class E(C,D):
        def __init__(self, a,b):
            super().__init__(a,b)
            print('init E...')
    
    e=E(1,2)
    
    e.show()
    
    print(e.b)
    
    print(E.mro())
http://python.jobbole.com/85685/

https://blog.csdn.net/m0_38063172/article/details/82250865
  1. 使用接口的思想设计多重继承

    整体可以分为类型类和功能类两种类,类型类实现主体继承树形结构,功能类作为独立的功能接口存在。

        #-*- coding:UTF-8 -*-
        
        # 多重继承
        
        class Animal(object):
            def __init__(self,age):
                self.age=age
        
        # 大类:
        class Mammal(Animal):
            def __init__(self,age,foot):
                super(Mammal,self).__init__(age)
                self.foot=foot
        
        class Bird(Animal):
            def __init__(self,age,fly):
                super(Bird,self).__init__(age)
                self.fly=fly
        
        
        
        class RunnableMixIn(object):
            def run(self):
                print('Running...')
        
        class FlyableMixIn(object):
            def fly(self):
                print('Flying...')
        
        # 各种动物:
        class Dog(Mammal,RunnableMixIn):
            def __init__(self,age,foot,gender):
                super(Dog,self).__init__(age,foot)
                self.gender=gender
            def show(self):
                print('dog age is:',self.age,'ang have ',self.foot)
        class Bat(Mammal, RunnableMixIn, FlyableMixIn):
            pass
        
        class Parrot(Bird,RunnableMixIn, FlyableMixIn):
            pass
        
        class Ostrich(Bird,RunnableMixIn):
            pass
        
        dog=Dog(3,4,'male')
        
        dog.show()
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,264评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,549评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,389评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,616评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,461评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,351评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,776评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,414评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,722评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,760评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,537评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,381评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,787评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,030评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,304评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,734评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,943评论 2 336

推荐阅读更多精彩内容

  • 初识面向对象 楔子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战...
    go以恒阅读 905评论 0 6
  • 写在前面的话 代码中的# > 表示的是输出结果 输入 使用input()函数 用法 注意input函数输出的均是字...
    FlyingLittlePG阅读 2,709评论 0 8
  • property、魔法属性和魔法方法、多重继承和多继承 1.5 property 学习目标 1. 能够说出什么要...
    Cestine阅读 784评论 0 1
  • 20- 枚举,枚举原始值,枚举相关值,switch提取枚举关联值 Swift枚举: Swift中的枚举比OC中的枚...
    iOS_恒仔阅读 2,209评论 1 6
  • 我们在安逸的时候会有种错觉,以为我们进入了生活的深层次,以为我们已经在某一个成熟的阶段,以为我们在一个相对结尾的环...
    Tina嬷嬷阅读 210评论 0 1