标签:nbsp set normal 条件判断 系统 trace 查看 限制 通过
isinstance 和 issubclass
通过例子看:
isinstance
class Foo(object): def __init__(self,name,sex): self.name=name self.sex=sex def printer(self): print(‘kkkkkkkkkkkk‘) f1=Foo(‘abc‘,‘male‘) print(isinstance(f1,Foo))#f1是不是Foo的对象
issubclass
class Foo(object): pass class Bar(Foo): pass print(issubclass(Bar,Foo)) # Bar 是不是Foo 的子类
>>> class Foo(object): def __init__(self,name,sex): self.name=name self.sex=sex def printer(self): print(‘kkkkk‘) >>> f1=Foo >>> hasattr(f1,‘name‘) #判断 f1 对象中有没有‘name’这个方法或属性 True
getattr
>>> getattr(f1,‘sex‘) #获取 f1 对象中的‘sex’ 属性或方法 ‘male‘ >>> getattr(f1,‘abcd‘) Traceback (most recent call last): File "<pyshell#19>", line 1, in <module> getattr(f1,‘abcd‘) AttributeError: ‘Foo‘ object has no attribute ‘abcd‘
setattr
>>> setattr(f1,‘name‘,‘david‘) #设置 f1 对象中 ‘name‘ 方法或属性的值,有则更改为‘david’ ,没有则添加至__dict__字典中 >>> print(f1.name) david >>> setattr(f1,‘age‘,32) >>> print(f1.age) 32 >>> print(f1.__dict__) # 查看对象的数据属性存放
{‘age‘: 32, ‘sex‘: ‘male‘, ‘name‘: ‘david‘}
delattr
>>> delattr(f1,‘age‘) #删除对象的属性值 >>> print(f1.__dict__) {‘sex‘: ‘male‘, ‘name‘: ‘david‘} >>> delattr(f1,‘sex‘) >>> print(f1.__dict__) {‘name‘: ‘david‘}
反射当前模块属性:
反射当前模块的属性: 先定义一个类 >>> class test: name=‘tony‘ sex=‘man‘ def __init__(self): print(‘hello‘) def priter(self): print(‘this printer %s‘%self.sex) print(self.name) >>> this_module=sys.mod >>> this_module=sys.modules[__name__] #这个 __name__ 说的是这个模块唯一标识导入系统中的模块 >>> print(this_module) <module ‘__main__‘ (built-in)> >>> hasattr(test,‘__init__‘) #相当于 ‘__init__‘ in test.__dict__ ,hasattr 做的就是这个事情 True >>> p=test() hello >>> setattr <built-in function setattr> #修改其属性 >>> setattr(p,‘name‘,‘liang‘) >>> print(p.name) liang
反射的用途:
#两个程序员写一个FTP,Tony,Hua,Tony写程序有些需要用到Hua 所写的类, ,但是Hua 因为有事外出,没有完成要写的类,Tony想到了反射可以继续完成自己的代码,等Hua回来再继续完成类的定义,并且去实现Tony想要的功能。
#反射的好处就是,可以事先定义好接口,接口只有在完成后才会真正执行,这就实现了‘即插即用’,这就是一种‘后期绑定’,就是可以事先把主要的逻辑写好(只定义接口),然后再去实现接口的功能
两个文件,一个是ftpserver, 一个是ftpclient ,tony负责Client端的编写,Hua负责Server端的编写
tony没有写完
class FtpCli: def __init__(self,addr): print(‘正在连接服务器 [%s]‘ % addr) self.addr=addr
Hua可以判断tony客户端写了没有,这就用到了反射,如果写了就执行那一部分的代码,如果没有就继续写其它模块:
import FtpClient f1=FtpClient.FtpCli(‘192.168.1.1‘) # print(f1) if hasattr(f1,‘get‘): #判断 tony的代码中有没有写get功能。 有则获取运行 func_get=getattr(f1,‘get‘) func_get() else: #没有则继续运行其它的代码 print(‘other runing‘)
实际应用:二次加工(包装)
#基于继承的原理来定制自己的数据类型
利用反射定制自己的数据类型,如列表、字典,我们可以定制‘值’ 必须是字符串,如:数据库的ID号,必须是int型。那这个时个可以用到“反射”
>>> class List(list): #定义列表类,继承 python 的list def append(self,value): #重写它的append方法 if not isinstance(value,int): #判断输入的值是不是 int类型 raise TypeError(‘Must be int‘) #不是int类型,则举出 ‘必须是int’ 的错误 else: super().append(value) #如果是整型,则使用超类(list)的append方法添加值到列表。 自定义的类是没有append 这些方法的 >>> l1=List([1,2,2,3,4,5,]) #实例化List 类 [1, 2, 2, 3, 4, 5] >>> l1.append(0) [1, 2, 2, 3, 4, 5, 0] >>> l1.append(‘3‘) Traceback (most recent call last): File "<pyshell#106>", line 1, in <module> l1.append(‘3‘) File "<pyshell#100>", line 4, in append raise TypeError(‘Must be int‘) TypeError: Must be int >>>
上面的都理解没有问题:
>>> l1.insert(0,‘fda‘) 这又是怎么回事呢? 这里的insert 不是我们自己定义的List 中的 insert ,因为没有经过自己定制,那l1就自己执行超类的 insert 方法了。 除非,自己再定制一个 insert ,再进行一次判断,不能insert 字符串。
>>> l1
[‘fda‘, 1, 2, 2, 3, 4, 5, 0]
授权:
不能用继承,实现字典的功能: 字典的值只能是str类型:
#不使用继承 完成字典的数据定制,字典的值必须是int , class Dict: def __init__(self,key,value): # 设置值:字典只有key和value if not isinstance(value,int): # 设置 字典的值只能是int 类型 raise TypeError(‘must be int‘) # 不是int 类型则报出错误 else: self.key=key #如果是字典类型 则把key的值传进来 self.c = {key: value} # 初始一个字典,这样就可以限制 健和值了 self.value = value #值 赋给self.value def fu_oprate(self,key,value): #字典操作 ,也是有键和值 if not isinstance(value,int): # 条件判断 传进来的值只能是int ,不是整型则报出错误 raise TypeError(‘must be int‘) # 报出错误 if not isinstance(key,str): #条件判断‘键’ ,只能是字符串类型 raise TypeError(‘must be str‘) #不是字符串类型,报错 else: self.c[key]=value #如果上述条件都成立,那就将 ‘值‘ 赋给‘键’ return self.c #返回整个字典 di1=Dict(‘name‘,‘tony’) #实例化 Dict print(di1.fu_oprate(‘age‘,‘fifteen‘)) # 操作字典,这里就已经限制了‘值’的数据类型,这就已经完成自定义数据类型的定制
结果:
完工~~~~~~
标签:nbsp set normal 条件判断 系统 trace 查看 限制 通过
原文地址:http://www.cnblogs.com/tonycloud/p/6758717.html