当继承的类有同种方法的时候,只会继承前面一个的方法。调用父类方法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 ’ '''
#类属性: __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 '''
装饰器(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 () ########## 留个映像,用的不是很多
@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)
5.作业
1.测试type 和 isinstance 那个的速度更快

import time def run_time(func): def new_fun(): t0 = time.time() print(t0) func() t1 = time.time() - t0 return t1 return new_fun @run_time def test_type(): for i in range(100): i = i*2 type(i) == int print('结束') @run_time def test_isinstance(): for i in range(100): i = i*2 isinstance(i,(int,float)) print('结束') def test(): a=test_type() #t1 b=test_isinstance() #t1 if a>b: print('isinstance更快') else: print('type更快')
2.实现一个正方形类的加减乘除(就那些魔术方法,能写多少写多少)

class Square(object): def __init__(self,length): self.length = length self.area = length**2 def __add__(self,other): # __add__ return self.area + other.area def __sub__(self,other): return self.area - other.area def __mul__(self,other): return self.area * other.area def __truediv__(self,other): return self.area / other.area