1.多继承

 

当继承的类有同种方法的时候,只会继承前面一个的方法。调用父类方法super()

 

#1.多继承

 

class Base:

       def play(self):

              print('这是Base')

 

class A(Base):

       def play(self):

              print(type(self))

              print('这是A')

 

class B(Base):

       def play(self):

              print('这是B')

 

class C(A,B):

    

       #子类调用父类方法

       def play(self):

              #A.play(self)  #第一种方法

              #B.play(self)

 

              #super().play()     #第二种方法,默认调用第一个父类方法

              #super(C,self).play() #括号不写,默认(C,self)

 

              #super(A,self).play()  # Base

              #super(B,self).play()   # A   ,  上一层

              #super(Base,self).play()

              print('这是C')

        

c = C()  # (B,A)  C  -> B  -> A  -> Base  ->object

 

             # (A,B)  C  -> A  -> B  -> Base  ->object

 

C().__class__.mro()

 

'''

super, 上一层

1.super(),    (自己类名,自己实例) 例:( C,c )

 

2. 谁调用我,我就以你为基准。 建立一张调用顺序表

    ‘(B,A)   C  -> B  -> A  -> Base  ->object ’

 

 

‘''

 


  2.类的特殊方法

 

#类属性:

    __dict__     # 类的属性(包含一个字典,由类的数据属性组成)

    __doc__     # 类的文档字符串

 

#类方法:  

    __init__    # 初始化

    __repr__    # 直接返回这个对象  repr() 函数就是调用对象的这个方法

    __str__     # print(obj) 如果类里面定义了__repr__,没有定义__str__ print(obj)也会返回__repr__的内容,或者说__repr__的优先级更高

    __call__    # Obj() 使实例可被调用

    

#运算符方法

    __add__(self,other)     #x+y

    __sub__(self,other)     #x-y 

    __mul__(self,other)     #x*y  

    __mod__(self,other)    #x%y

    __iadd__(self,other)     #x+=y

    __isub__(self,other)     #x-=y 

    __radd__(self,other)    #y+x

    __rsub__(self,other)     #y-x 

    __imul__(self,other)     #x*=y 

    __imod__(self,other)    #x%=y 

    

#和类有关的几个函数  

    delattr()        # 删除对象属性

    getattr()        # 得到某个属性值

    setattr()        # 给对象添加某个属性值

    hasattr()          # 判断对象object是否包含名为name的特性

    isinstance()      # 检查对象是否是类的对象,返回True或False

    issubclass()      # 检查一个类是否是另一个类的子类。返回True或False    

 

'''

不仅仅是属性,更多是方法

 

'''

 

class Rectangle:

       '''这是一个长方形类,它可以计算面积'''

       aaa = 1

       def __init__(self,length,width):     #构造方法

            if isinstance(length,(int,float)) and isinstance(width,(int,float)):

                   self.length = length

                   self.width = width

             else:

                    print('请输入int or float')

 

    def area(self):

        return self.length * self.width

 

##    def __str__(self):

##        return  '这个长方形的面积%s'%self.area()

 

    def __repr__(self):

           return '长:%s  宽:%s'%(self.length,self.width)

 

    def __call__(self):

           return '我这是一个Rectangle 类,你要干嘛'

 

    def __add__(self,other):

           return self.area() + other.area()

        

    def __sub__(self,other):

           return '不可以相减'

 

r = Rectangle(2,3)

 

#类属性

 

#__dict__ 

 

r.__dict__   # 打印实例里面的属性 ,{'length': 2, 'width': 3}

 

 

#注意  ,共有属性。当不修改时,默认引用(源类 Rectangle ),

                                 # 修改之后,就会定义在 实例里面

r.aaa = 22

r.__dict__

 

#__doc__

r.__doc__

 

#类方法 

 

#__str__    

#print(r)

 

#__repr__

r

 

'%s'%'ssss'   

'%r'%'rrrr'

 

#print  默认调用__str__   ,没有时__repr__

 

####  __call__

#r()

r()  # '我这是一个Rectangle 类,你要干嘛'

 

def dd():

    print('dd')

 

dir(dd)   #'__call__'

 

r1 = Rectangle(2,4)

r2 = Rectangle(3,5)

 

#   __add__(self,other)

 

#__sub__(self,other)     #x-y 

 

####

'''

delattr()        # 删除对象属性

getattr()        # 得到某个属性值

setattr()        # 给对象添加某个属性值

hasattr()          # 判断对象object是否包含名为name的特性

isinstance()      # 检查对象是否是类的对象,返回True或False

issubclass()      # 检查一个类是否是另一个类的子类。返回True或Fals

'''

 


  3.装饰器

 

装饰器(deco):

        装饰函数的参数是被装饰的函数对象,返回原函数对象装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象

         概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

 

###3.装饰器 ,添加附加功能

 

#闭包

 

def fx(x):

       x += 1

       def fy(y):

              return x*y

    

       return fy

 

'''

fx(1)(2)

temp = fx(1)

temp(2)

'''

 

def f1(func):

       print('f1 running')

       def f2(y):

              print('f2 running')

              return func(y)+1

       return f2

    

def gun(m):

       print('gun running')

       return m*m

 

'''

f1(gun)

temp = f1(gun)

temp(5)

'''

 

@f1

def gun2(m):

       print('gun running')

       return m*m

 

'''

1.  @f1  ->   f1( gun2 )   -> f2

2.  f2  ,等待调用

3.  gun2   (5)  ->  当参数 5传入 --> f2(5)

4.  f2(5), 开始运行  ->  print('f2 running') ->  func(y): func = gun2  y = 5  ->{{func(y) 等于 gun2(5)}}

5.  gun2(5) 开始运行  -> print('gun running') ->  25

6.  25 +1  -> 26

 

'''

 

##测试时间

 

'''

import time   

def run_time(func):

    def new_fun(*args,**kwargs):

        t0 = time.time()

        print('star time: %s'%(time.strftime('%x',time.localtime())) )

        back = func(*args,**kwargs)

        print('end time: %s'%(time.strftime('%x',time.localtime())) )

        print('run time: %s'%(time.time() - t0))

        return back

    return new_fun

 

'''

 

import time  #不要纠结

 

def run_time(func):

       def new_fun():

              t0 = time.time()

              print('star time: %s'%(time.strftime('%x',time.localtime())) )

              func()

              print('end time: %s'%(time.strftime('%x',time.localtime())) )

              print('run time: %s'%(time.time() - t0))

        

       return new_fun

 

 

 

@run_time

def test():

       for i in range(1,10):

             for j in range(1,i+1):

                   print('%dx%d=%2s'%(j,i,i*j),end = ' ')

        print ()

   

##########  留个映像,用的不是很多

 


  4.类装饰器

 

@property 

    装饰过的函数返回的不再是一个函数,而是一个property对象

    装饰过后的方法不再是可调用的对象,可以看做数据属性直接访问。

@staticmethod #(静态方法)

    把没有参数的函数装饰过后变成可被实例调用的函数,      

    函数定义时是没有参数的,可以不接收参数

 

@classmethod (类方法)

    把装饰过的方法变成一个classmethod类对象,既能能被类调用又能被实例调用。

    注意参数是cls代表这个类本身。而是用实例的方法只能被实例调用。     

        

一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。

而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。

这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁

 

##类装饰器

class Test_Class():

       def __init__(self,func):

             self.func = func

 

       def __call__(self):

             print('类')

             return self.func

 

@Test_Class

def  test():

    print('这是一个测试')

 

test()  #    self.func : test 函数体

test()()

 

# 1. @Test_Class : Test_Class( test ) -> 相当于:t = Test_Class( test )# 2. test() -> 相当于: t() 调用实例的call方法 -> 返回 self.func函数体# 3. test()() 调用test()

 

###python自带3个,类的内置装饰器

class Rectangle:

    '''这是一个长方形类,它可以计算面积'''

    aaa = 1

    def __init__(self,length,width):     #构造方法

           if isinstance(length,(int,float)) and isinstance(width,(int,float)):

               self.length = length

               self.width = width

         else:

                print('请输入int or float')

 

    @property  # 可以把方法,当成属性一样调用  , r.area

    def area(self):

        return self.length * self.width

    

    @staticmethod   #静态方法, 不用self了,实例可以直接调用

    def func():

           print('可以调用吗?')

 

    @classmethod   #将实例,还原成了类cls   self实例

    def show(cls):

           print(cls)

           print('show fun')

 

 

r = Rectangle(2,3)