pythonx1_面向对象

作者: 詹亮的小仓库 | 来源:发表于2020-04-15 10:17 被阅读0次

    面向对象

    基础

    ===

    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()
      

    相关文章

      网友评论

        本文标题:pythonx1_面向对象

        本文链接:https://www.haomeiwen.com/subject/gqmqvhtx.html