我的python之路【第七章】面向对象编程高级
什么是类和对象
class Garen: camp='Demacia' def __init__(self,nickname,aggresivity,life_value): self.nickname=nickname self.aggresivity=aggresivity self.life_value=life_value def attack(self,enemy): print('is attacting') #类的第一个功能:实例化 g1=Garen('草丛伦',82,100) #类的的第二个功能:属性引用,包含数据属性和函数属性 g1.attack(2222) #对于一个实例来说,只有一个功能:属性引用,实例本身只拥有数据属性 print(g1.nickname) print(g1.aggresivity) print(g1.life_value)
接口与归一化设计
#接口的概念,父类只写名字,不写实现 class ALLFile: #接口类 def read(self): #接口函数 pass def write(self): pass class Text(ALLFile): #子类继承父类 def read(self): print('text read') def write(self): print('text write') class Sata(ALLFile): #子类继承父类 def read(self): print('sata read') def write(self): print('sata write') t=Text() s=Sata() t.read() t.write() s.read() s.write()
抽象类
import abc class ALLFile(metaclass=abc.ABCMeta): #抽象类 @abc.abstractmethod #加这个装饰器的必须在子类中实现 def read(self): # pass @abc.abstractmethod #加这个装饰器的必须在子类中实现 def write(self): pass def test(self):#可以不被实现 print('22222222') class Text(ALLFile): #子类中必须实现父类中规定的两个方法 def read(self):pass def write(self):pass t1=Text() t1.test() # 抽象类不能被实例化, # a=ALLFile()
反射
class Foo: def __init__(self,name): self.name=name def func(self): print('func') f = Foo('egon') print(Foo.__dict__) print(f.__dict__) #hasattr判断类中是否有这个func的名字 print(hasattr(Foo,'func')) #判断实例中是否有x这个属性 print(hasattr(f,'x')) f.x=1 #根据字符串,调用实例中的属性 print(getattr(f,'x')) #常用组合 if hasattr(f,'func'): getattr(f,'func')() #调用,如果没有,返回None print(getattr(f,'y',None)) #设置一个属性 #f.y=1 setattr(f,'y',1)
属性方法:
class A: def __init__(self,name): self.__name=name @property #将这个类中的方法,变成一个类中的属性,可以通过.name调用 def name(self): return self.__name #当调用.name时返回的是__self.name @name.setter #赋值操作调用,当为.name赋值时调用 def name(self,value): # print('------') if not isinstance(value,str): #判断赋值的是不是字符 raise TypeError('%s must be str'%value)#抛出异常 self.__name=value @name.deleter #删除.name属性时调用 def name(self): print('=====') del self.__name a=A('ennn') print(a.name) a.name='ssa' print(a.name) del a.name
继承
class A: #默认继承object pass class B(A):#继承A pass #打印继承的父类 print(B.__bases__) #继承了 print(A.__bases__) # #新式的类 class Animal: start='earth' def __init__(self,name,age,gender): self.name=name self.age=age self.gender=gender def run(self): print('running') def talk(self): print('talking') class People(Animal): pass def piao(self): print('大保健') class Pig(Animal): pass p1=People('alex',50,'F') pig1=Pig('贺磊',250,'22') print(p1.start) p1.run()
#继承可以重用代码 class Hero: def __init__(self,nickname,aggresivity,life_value): self.nickname=nickname self.aggresivity=aggresivity self.life_value=life_value def attack(self,enemy): print('is attacting',enemy.nickname) enemy.life_value-=self.aggresivity class Garen(Hero): camp='Demacia' class Riven(Hero): camp='Noxus'
子类继承父类的方法:super()
class People(object): def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex class Teacher(People): def __init__(self,name,age,sex,level): #People.__init__(name,age,sex) #需要知道父类的名字~ super().__init__(name,age,sex) #推荐用法 self.level=level t1=Teacher('alex',22,'m','高级') print(t1.name)
静态方法
@staticmethod
静态方法不属于实例,也不属于类
与类只是名义上的归属关系
@classmethod
类方法
只能访问类变量,不能访问实例变量
import time class Date: def __init__(self,year,month,day): self.year=year self.month=month self.day=day @staticmethod #静态方法 def now(): t=time.localtime() return Date(t.tm_year,t.tm_mon,t.tm_mday) '''打印: <__main__.Date object at 0x0000022298A754A8>''' @classmethod #改成类方法 def class_now(cls): t=time.localtime() return cls(t.tm_year,t.tm_mon,t.tm_mday) #哪个类来调用,即用哪个类cls来实例化 ''' 输出结果: year:2017 month:3 day:3 ''' class EuroDate(Date): def __str__(self): return 'year:%s month:%s day:%s' %(self.year,self.month,self.day) e=EuroDate.now() print(e) #我们的意图是想触发EuroDate.__str__,此时e就是由EuroDate产生的,所以会如我们所愿 print(EuroDate.class_now()) print(Date.now())
面向对象高级使用
class Foo: def __init__(self,name): self.name=name def __getitem__(self, item): print(self.__dict__[item]) def __setitem__(self, key, value): self.__dict__[key]=value def __delitem__(self, key): print('del obj[key]时,我执行') self.__dict__.pop(key) def __delattr__(self, item): print('del obj.key时,我执行') self.__dict__.pop(item) f=Foo('egon') print(f['name']) f['x']=1 print(f.__dict__) del f.x #del f['x']
创建类的方法:追本溯源
#创建两个函数 def init(self,name,age): self.name=name self.age=age def sayhi(self): print('hello',self.name) #使用type方法创建类 Test=type('Test',(object,),{'sayhi':sayhi,'__init__':init}) #生成实例 test_obj=Test('liuhao','22') #调用实例方法 test_obj.sayhi()
'''__new__:object继承到的方法:用途是生成实例对象''' class Foo(object): def __init__(self,name): self.name=name print('Foo__init__') #__new__:生成实例的方法 def __new__(cls, *args, **kwargs): #覆盖了object中的new '''这里负责调用实例化,事实:就是将类的内存地址复制一份,开辟一块新的内存空间,打算给实例用 这里就是生成实例对象的内存地址,并且返回 ''' print('Foo __new__') #object.__new__(cls) #实例化后的内存地址 obj=object.__new__(cls) print('obj',dir(obj)) print(obj) return obj #返回obj这个内存空间 f=Foo('alex') print(dir(f)) print(f) print(f.name)
metaclass
class MyType(type): def __init__(self,*args,**kwargs): print('MyType __init__',self,*args,**kwargs) def __new__(cls, *args, **kwargs): print('MyType __new__',cls,*args,**kwargs) obj=type.__new__(cls,*args,**kwargs) return obj def __call__(self, *args, **kwargs): #在f=Foo('Alex') 时调用 self =Foo *args = 'Alex' #这里传入的self 是已经执行完成MyType中__init__ 和 __new__ 的。 执行完的过程 __new__ 返回了obj = type.__new__(cls) 这个时候 self 中__new__ 其实就是 type.__new__ print('MyType __call__',self,*args,**kwargs) # print(self.__new__) obj=self.__new__(self) #这里执行的是object中继承的.__new__(cls) self.__init__(obj,*args,**kwargs) #Foo 中的__init__已经重写 obj.age=22 return obj class Foo(object,metaclass=MyType): def __init__(self,name): self.name=name print('Foo __init__ ') # print(__init__) #下面全部注释状态下 ''' 会通过MyType生成 Foo这个类:对于MyType来说也是一个对象 先执行Mype__new__() 再执行Mype__init__() MyType __new__ <class '__main__.MyType'> Foo (<class 'object'>,) {'__init__': <function Foo.__init__ at 0x0000020EDCCF98C8>, '__qualname__': 'Foo', '__module__': '__main__'} MyType __init__ <class '__main__.Foo'> Foo (<class 'object'>,) {'__init__': <function Foo.__init__ at 0x0000020EDCCF98C8>, '__qualname__': 'Foo', '__module__': '__main__'} ''' #相当于为Foo加() 默认会执行 __call__() 这里的Foo = MyType 中 __new__返回的内存地址 f=Foo('Alex') ''' 生成实例f :Foo加上() 执行MyType中的__call__() ''' print(Foo.__module__)
导入模块
import importlib __import__('lib.aa') # importlib.import_module('lib.aa')