多态&封装
多态
''' 多态 执行时候的一种状态 ''' ''' 类继承有2层意义: 1.改变 2.扩张 多态就是类的这两层意义的一个具体的实现方式 即,调用不同的类实例化得对象下的相同的方法,实现的过程不一样、 python 中的标准类型就是多态概念的一个很好的示范 '''
class H2O: def __init__(self,name,temperature): self.name = name self.temperature = temperature def turn_ice(self): if self.temperature <0: print('[%s] 温度太低结冰了'%self.name) elif self.temperature > 0 and self.temperature < 100: print('[%s]液化成冰'%self.name) elif self.temperature > 100: print('[%s] 温度太高变成水蒸气'%self.name) class Water(H2O): pass class Ice(H2O): pass class steam(H2O): pass w1 = Water('水',25) i1 = Ice('冰',-20) s1 = steam('蒸汽',333) # w1.turn_ice() # i1.turn_ice() # s1.turn_ice() def func(obj): obj.turn_ice() func(w1) #[水]液化成冰 func(i1) #[冰] 温度太低结冰了 func(s1) #蒸汽] 温度太高变成水蒸气
封装
class People: _start = '1234' __start1 = '5678' def __init__(self,id,name,age,salary): self.id = id self.name = name self.age = age self.salary = salary def get_id(self): print('%s'%self.id) p = People(200000,'yy',1,2000000) print(p._start) #1234 print(People._start) #1234 print(p.__dict__) print(People.__dict__) #里面包含 '_People__start1': '5678' print(People._People__start1) #5678 print(p._People__start1) #5678
class Room: def __init__(self,name,owner,width,length,high): self.name = name self.owner = owner self.__width = width self.__length = length self.__high = high def tell_area(self): return self.__width * self.__length def tell_width(self): return self.__width r1 = Room('卫生间','xx',100,100,1000) print(r1.tell_area())
'' 动态导入模块 ''' #1 module_1 = __import__('m1.t') print (module_1) #只导入了 m1 t没有被导入 # 2 import importlib m = importlib.import_module('m1.t') print(m) #m1.t 都导入了动态导入模块
反射
hasattr() ''' Return whether the object has an attribute with the given name. 返回对象是否具有给定名称的属性。 This is done by calling getattr(obj, name) and catching AttributeError. 这是通过调用GETAutr(Objo,name)和捕获属性错误来完成的。 ''' getattr() ''' getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y. When a default argument is given, it is returned when the attribute doesn't exist; without it, an exception is raised in that case. ''' setattr() """ Sets the named attribute on the given object to the specified value. setattr(x, 'y', v) is equivalent to ``x.y = v'' """ delattr() """ Deletes the named attribute from the given object. delattr(x, 'y') is equivalent to ``del x.y'' """
class BlackMedium: feturn = 'Ugly' def __init__(self,name,addr): self.name = name self.addr = addr def sell_hourse(self): print('【%s】 正在卖房子,傻逼才买呢' %self.name) def rent_hourse(self): print('【%s】 正在租房子,傻逼才租呢' % self.name) ll= BlackMedium('alex','NJ') print(hasattr(BlackMedium,'feturn1')) #判断是否有这个 print(hasattr(ll,'addr')) # True func = getattr(ll,'rent_hourse') #等于 11.rent_hourse func() #【alex】 正在租房子,傻逼才租呢 test = ll.rent_hourse test() #【alex】 正在租房子,傻逼才租呢 # print(getattr(ll,'rent_hourseasdfsa','没有这个属性')) #没有则报错 setattr(ll,'sb',True) print(hasattr(ll,'sb')) #True print(getattr(ll,'sb1','nono')) #nono delattr(ll,'sb') print(hasattr(ll,'sb')) #False
attr
''' __setattr__ __getattr__ __delattr__ '''
class Foo: x=1 def __init__(self,y): self.y=y def __getattr__(self, item): print('执行__getattr__') f1=Foo(10) print(f1.y) #10 print(getattr(f1,'y')) #10 #len(str)--->str.__len__() f1.ssssssssssssssssssssssss #调用一个对象不存在的,会触发 __getattr__
class Foo: x=1 def __init__(self,y): self.y=y def __delattr__(self, item): print('删除__delattr__') f1 = Foo(10) del f1.y #删除__delattr__ del f1.x #删除__delattr__ #删除会触发 __delattr__
class Foo: x=1 def __init__(self,y): self.y=y def __setattr__(self, key, value): print('__setattr__') self.__dict__[key]=value f1 = Foo(10) #__setattr__ print(f1.__dict__) #{'y': 10} f1.z = 20 #__setattr__ print(f1.__dict__) #{'y': 10, 'z': 20} #设置属性会触发 __setattr__
class Foo: def __init__(self,name): self.name = name def __getattr__(self, item): print('你找的属性不存在【%s】'%item) def __setattr__(self, key, value): print('执行setattr',key, value) # if type(value) is str: if isinstance(value,str): print('开始设置') # self.k = v #触发__setattr__ self.__dict__[key] = value else: print('必须字符串类型') def __delattr__(self, item): # print('不允许删除【%s】'%item) # del self.item #触发__delattr__ self.__dict__.pop(item) f1 = Foo('YY') print(f1.name) f1.age = '12' print(f1.__dict__) del f1.age print(f1.__dict__)
item
class Foo: def __getitem__(self, item): print('getitem',item) return self.__dict__[item] def __setitem__(self, key, value): print('setitem') self.__dict__[key]=value def __delitem__(self, key): print('delitem') self.__dict__.pop(key) f1=Foo() print(f1.__dict__) # f1.name='egon' #---->setattr-------->f1.__dict__['name']='egon' f1['name']='egon'#--->setitem--------->f1.__dict__['name']='egon' f1['age']=18 print('===>',f1.__dict__) #===> {'name': 'egon', 'age': 18} del f1['name'] #delitem print(f1.__dict__) # {'age': 18} print(f1['age']) #18
''' 二次加工标准类型 ''' class List(list): pass ll = List('helloworld') l2 = list('helloworld') print(ll,type(ll)) #['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'] <class '__main__.List'> print(l2,type(l2)) #['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'] <class 'list'> # # class List1(list): def show_midlle(self): mid_index = int(len(self)/2) return self[mid_index] ll = List1('helloworld') print(ll.show_midlle()) #w class List2(list): def append(self, p_object): if type(p_object) is str: #self.append(p_object) #这个是错误 #super().append(p_object) #调用父类的list 方法 方法一 list.append(self,p_object) #调用父类的list方法 方法二 else: print('只能添加字符串类型') l2 = List2('helloworld') l2.append('1111') print(l2) #基于继承 派生
授权
''' 授权 授权是包装的一个特性,包装一个类型通常是对已经存在的类型的一些定制,这种做法可以新建 修改或删除原有产品的功能,其他的则保持原样 授权的过程,及时所有更新的功能都是由新类的某部分来 处理,但已存在的功能就授权给对象的默认属性 __getattr__ ''' import time class Open: def __init__(self, filename, mode='r', encoding='utf-8'): # self.filename = filename self.file = open(filename, mode, encoding=encoding) self.mode = mode self.encoding = encoding def write(self, line): print('------------->', line) t = time.strftime('%Y-%m-%d %T') self.file.write('%s %s' % (t, line)) def __getattr__(self, item): return getattr(self.file, item) f1 = Open('a.txt', 'r+') print(f1.read()) f1.write('333333333333 ') f1.close()