一.isinstance和issubclass

  • isinstance(obj,cls)检查是否obj是否是类 cls 的对象

  • issubclass(sub, super)检查sub类是否是 super 类的派生类

Android培训,安卓培训,手机开发培训,移动开发培训,云培训培训 View Code

输出结果如下

Android培训,安卓培训,手机开发培训,移动开发培训,云培训培训 View Code

二.反射和相关的内置函数

  • 反射是指程序可以访问、检测和修改它自己本身状态或者行为的一种能力(自省)。

  • 而在Python中,反射其实就是通过字符串的形式访问或者修改对象的属性。这里的对象是指一切对象,类本身也是一个对象。

Android培训,安卓培训,手机开发培训,移动开发培训,云培训培训

 1 class People: 2     country = 'china' 3     def __init__(self,name,sex): 4         self.name = name 5         self.sex = sex 6     def walk(self): 7         print('walk') 8 p1 = People('silver_bullet','male') 9 print(hasattr(p1,'name'))              #hasattr(*args, **kwargs) 验证有没有该属性10 print(getattr(p1,'sex'))               #getattr(object, name, default=None) 获取一个属性,可以设置default11 print(setattr(p1,'age',22))            #setattr(x, y, v) 设置一个属性,返回值为None,所以用下面get方法验证12 print(getattr(p1,'age'))13 print(delattr(p1,'age'))               #delattr(x, 'y') is equivalent to del x.y 删除一个属性,返回值为None14 # print(getattr(p1,'age'))             #age属性已经被删除掉15 setattr(p1,'show_name',lambda self:self.name+' is excellent')#增加一个函数属性16 print(p1.show_name(p1))

Android培训,安卓培训,手机开发培训,移动开发培训,云培训培训

 

模块级别的反射

Android培训,安卓培训,手机开发培训,移动开发培训,云培训培训

1 import sys2 xxx = 1113 this_module = sys.modules[__name__]     #获取当前模块4 print(hasattr(this_module,'xxx'))5 print(getattr(this_module,'xxx'))6 setattr(this_module,'yyy','12345')7 print(getattr(this_module,'yyy'))

Android培训,安卓培训,手机开发培训,移动开发培训,云培训培训

反射的好处

  • 实现可插拔机制。可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,即你可以事先把主要的逻辑写好(只定义接口), 然后后期再去实现接口的功能。 

  • 动态导入模块(基于反射当前模块成员)。

1 import importlib2 t = importlib.import_module('time')     #通过字符串的形式导入模块,推荐使用importlib3 print(t.time())                         #不推荐__import__(m),m为字符串,这个是python解释器自己使用的

三.内置函数(__attr__相关)

Android培训,安卓培训,手机开发培训,移动开发培训,云培训培训

 1 class Foo: 2     '内置函数__attr__的使用' 3     def __init__(self,name): 4         self.name = name                   #这个也会触发__setattr__的执行 5     def __setattr__(self, key, value):     #给属性赋值都会触发__setattr__,把key和value都赋值,可以做类型判断,弥补python没有类型限制 6         self.__dict__[key] = value         #直接在dict字典中添加相应的键值对即可,key和value都为字符串 7         print('from __setattr__') 8     def __delattr__(self, item):           #del 操作会触发这个内置函数 9         self.__dict__.pop(item)            #直接在dict字典中删除相应的键值对即可10         print('from __delattr__',type(item))# type(item)--------->str11     def __getattr__(self, item):           #注意:属性获取不到,才会触发这个内置函数!!!12         print('get__attr__---->{0},{1}'.format(item,type(item)))13 14 f = Foo('silver_bullet')                   #触发__init__里就有一个赋值,即会触发__settattr__15 f.time = 55516 print(f.__dict__)17 print(f.time)18 del f.time                                  #触发__del__内置函数19 print(f.__dict__)20 f.xxx                                       #这个才会触发__getattr__的执行,没有找到xxx的属性,而现在却没有报错

Android培训,安卓培训,手机开发培训,移动开发培训,云培训培训

四.定制自己的数据类型

  • 继承的方式 

Android培训,安卓培训,手机开发培训,移动开发培训,云培训培训

 1 class my_list(list):                   #基于继承 2     def __init__(self,seq): 3         for i in seq: 4             if not isinstance(i,str): 5                 raise TypeError('This is not a str list') 6             else: 7                 super().append(i) 8     def append(self, object: str): 9         if not isinstance(object,str):10             raise TypeError('must be str')11         super().append(object)12     @property13     def mid_value(self):14         mid_index = len(self)//215         return self[mid_index]16 17 l = my_list(['a'])18 print(l)19 l.append('1')20 print(l)21 print(l.mid_value)22 l.insert(0,4)23 print(l)

Android培训,安卓培训,手机开发培训,移动开发培训,云培训培训

  • 授权的方式  

Android培训,安卓培训,手机开发培训,移动开发培训,云培训培训

 1 class my_list():                                 #基于授权 2     def __init__(self,seq): 3         for i in seq: 4             if not isinstance(i,str): 5                 raise TypeError('This is not a str list') 6         self.seq = list((seq))                    #使用一个中间属性self.seq保存这个列表 7     def __str__(self):                            #override  __str__,才能够打印列表的显示,否则打印的是一个对象地址 8         return str(self.seq) 9     def append(self, object: str):               #重新定制这个append10         if not isinstance(object,str):11             raise TypeError('must be str')12         self.seq.append(object)                  #实际上是在这里使用13     @property14     def mid_value(self):                         #定制一个属性,返回中间值。15         mid_index = len(self.seq)//216         return self.seq[mid_index]17     def __getattr__(self, item):                 #其余方法都使用list默认的18         func = getattr(self.seq,item)            #直接返回getattr的函数名19         return func20     def __getitem__(self, item):                 #加上以下三个item操作,才能够支持索引,切片,赋值和del删除21         return self.seq[item]22     def __setitem__(self, key, value):23         self.seq[key] = value24     def __delitem__(self, key):25         self.seq.pop(key)26         27         28 l = my_list(['a'])29 print(l)30 l.append('1')31 print(l[1])32 print(l.mid_value)33 l.insert(0,4)34 l[0]='123'35 print(l)36 print(l[1:])

Android培训,安卓培训,手机开发培训,移动开发培训,云培训培训

 

五.给日志文件加时间头

使用授权的方式重写open

Android培训,安卓培训,手机开发培训,移动开发培训,云培训培训

 1 import time 2 class Open: 3     'override File  write' 4     def __init__(self,path,mode = 'r',encoding = 'GBK'): 5         self.fw = open(path,mode=mode,encoding=encoding)        #这里要写成位置参数的形式,取到文件句柄赋值给self.f 6     def write(self,line): 7         now_time = time.strftime('%Y-%m-%d-%X')                 #字符串形式显示time时间 8         self.fw.write('{0}\n'.format(now_time))                 #添加日志文件的时间头 9         self.fw.write(line)                                     #写想要输入到文件里面的内容10     def __getattr__(self, item):                                #不想要改写的地方定义在__getattr__中,找不到的属性会触发这个内置函数11         func = getattr(self.fw,item)                            #通过getattr的方法,将函数名的入口地址获取到并且返回12         return func13 14 f = Open('a.txt','w+')                                           #触发__init__方法15 for i in range(2):16     f.write('11111111111\n')17     time.sleep(0.5)18 f.seek(0)19 print(f.readlines())

Android培训,安卓培训,手机开发培训,移动开发培训,云培训培训

 

http://www.cnblogs.com/yangming111/p/6758328.html

网友评论