python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。
Python getattr() 函数
描述
getattr() 函数用于返回一个对象属性值。
语法
getattr 语法:
getattr(object, name[, default])
参数
- object -- 对象。
- name -- 字符串,对象属性。
- default -- 默认返回值,如果不提供该参数,在没有对应属性时,将触发 AttributeError。
返回值
返回对象属性值。
1 >>>class A(object): 2 ... bar = 1 3 ... 4 >>> a = A() 5 >>> getattr(a, 'bar') # 获取属性 bar 值 6 1 7 >>> getattr(a, 'bar2') # 属性 bar2 不存在,触发异常 8 Traceback (most recent call last): 9 File "<stdin>", line 1, in <module> 10 AttributeError: 'A' object has no attribute 'bar2' 11 >>> getattr(a, 'bar2', 3) # 属性 bar2 不存在,但设置了默认值 12 3 13 >>>
Python hasattr() 函数
描述
hasattr() 函数用于判断对象是否包含对应的属性。
语法
hasattr 语法:
hasattr(object, name)
参数
- object -- 对象。
- name -- 字符串,属性名。
返回值
如果对象有该属性返回 True,否则返回 False。
实例
以下实例展示了 hasattr 的使用方法:
1 #!/usr/bin/python 2 # -*- coding: UTF-8 -*- 3 4 class Coordinate: 5 x = 10 6 y = -5 7 z = 0 8 9 point1 = Coordinate() 10 print(hasattr(point1, 'x')) 11 print(hasattr(point1, 'y')) 12 print(hasattr(point1, 'z')) 13 print(hasattr(point1, 'no')) # 没有该属性
Python setattr() 函数
描述
setattr 函数对应函数 getatt(),用于设置属性值,该属性必须存在。
语法
setattr 语法:
setattr(object, name, value)
参数
- object -- 对象。
- name -- 字符串,对象属性。
- value -- 属性值。
返回值
无。
实例
以下实例展示了 setattr 的使用方法:
>>>class A(object): ... bar = 1 ... >>> a = A() >>> getattr(a, 'bar') # 获取属性 bar 值 1 >>> setattr(a, 'bar', 5) # 设置属性 bar 值 >>> a.bar 5
Python delattr() 函数
描述
delattr 函数用于删除属性。
delattr(x, 'foobar') 相等于 del x.foobar。
语法
setattr 语法:
delattr(object, name)
参数
- object -- 对象。
- name -- 必须是对象的属性。
返回值
无。
实例
以下实例展示了 delattr 的使用方法:
1 #!/usr/bin/python 2 # -*- coding: UTF-8 -*- 3 4 class Coordinate: 5 x = 10 6 y = -5 7 z = 0 8 9 point1 = Coordinate() 10 11 print('x = ',point1.x) 12 print('y = ',point1.y) 13 print('z = ',point1.z) 14 15 delattr(Coordinate, 'z') 16 17 print('--删除 z 属性后--') 18 print('x = ',point1.x) 19 print('y = ',point1.y) 20 21 # 触发错误 22 print('z = ',point1.z)
1 #!/usr/bin/env python3 2 #-*- coding:utf-8 -*- 3 ''' 4 Administrator 5 2018/7/26 6 ''' 7 from inspect import isfunction 8 class Foo: 9 def __init__(self,name,age): 10 self.name=name 11 self.age=age 12 def show(self): 13 print('ok') 14 return '%s----%s'%(self.name,self.age) 15 16 obj=Foo("诸葛亮",27) 17 18 # while True: 19 # b=input("请输入要查看的属性或字段:>>>") 20 # v=getattr(obj,b) 21 # print(v()) 22 # if isfunction(v): 23 # s=v() 24 # print(s) 25 # else: 26 # s=v 27 # print(s) 28 #####若只给b='name',怎么从obj中拿出对象的名字########## 29 b='name' 30 # 31 # #通过字典拿到 __dic__ 32 # # print(obj.__dict__[b]) 33 # v=getattr(obj,b) 34 # print(v) 35 36 37 # print(hasattr(obj,b)) 38 setattr(obj,"kq","钮鹏程")#放到对象的内存中 39 print(obj.kq) 40 41 delattr(obj,b) 42 print(obj.age)
导入模块
1 name="中国" 2 3 def fn(): 4 return 'ok' 5 6 class Foo: 7 def __init__(self): 8 self.name=123
s1
1 import s2 2 3 r1=s2.name 4 print(r1) 5 6 r2=s2.fn() 7 print(r2) 8 9 print(getattr(s2,'name')) 10 print(getattr(s2,'fn')()) 11 obj_cls=getattr(s2,'Foo') 12 print(obj_cls) 13 A=obj_cls() 14 print(A.name)
1 #!/usr/bin/env python3 2 #-*- coding:utf-8 -*- 3 ''' 4 Administrator 5 2018/7/26 6 ''' 7 """ 8 from inspect import isfunction 9 class Foo: 10 def __init__(self,name,age): 11 self.name=name 12 self.age=age 13 def show(self): 14 print('ok') 15 return '%s----%s'%(self.name,self.age) 16 17 obj=Foo("诸葛亮",27) 18 19 # while True: 20 # b=input("请输入要查看的属性或字段:>>>") 21 # v=getattr(obj,b) 22 # print(v()) 23 # if isfunction(v): 24 # s=v() 25 # print(s) 26 # else: 27 # s=v 28 # print(s) 29 #####若只给b='name',怎么从obj中拿出对象的名字########## 30 b='name' 31 # 32 # #通过字典拿到 __dic__ 33 # # print(obj.__dict__[b]) 34 # v=getattr(obj,b) 35 # print(v) 36 37 38 # print(hasattr(obj,b)) 39 setattr(obj,"kq","钮鹏程")#放到对象的内存中 40 print(obj.kq) 41 42 delattr(obj,b) 43 print(obj.age) 44 """ 45 import s2 46 47 r1=s2.name 48 print(r1) 49 50 r2=s2.fn() 51 print(r2) 52 53 print(getattr(s2,'name')) 54 print(getattr(s2,'fn')()) 55 obj_cls=getattr(s2,'Foo') 56 print(obj_cls) 57 A=obj_cls() 58 print(A.name)
一、isinstance(obj, cls)
检查是否obj是否是类 cls 的对象
class Foo(object): pass obj = Foo() isinstance(obj, Foo)
二、issubclass(sub, super)
检查sub类是否是 super 类的派生类
class Foo(object): pass class Bar(Foo): pass issubclass(Bar, Foo)
1 #!/usr/bin/env python 2 #coding:utf-8 3 from wsgiref.simple_server import make_server 4 5 class Handler(object): 6 7 def index(self): 8 return 'index' 9 10 def news(self): 11 return 'news' 12 13 14 def RunServer(environ, start_response): 15 start_response('200 OK', [('Content-Type', 'text/html')]) 16 url = environ['PATH_INFO'] 17 temp = url.split('/')[1] 18 obj = Handler() 19 is_exist = hasattr(obj, temp) 20 if is_exist: 21 func = getattr(obj, temp) 22 ret = func() 23 return ret 24 else: 25 return '404 not found' 26 27 if __name__ == '__main__': 28 httpd = make_server('', 8001, RunServer) 29 print "Serving HTTP on port 8000..." 30 httpd.serve_forever()
结论:反射是通过字符串的形式操作对象相关的成员。一切事物都是对象!!!
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import sys 5 6 7 def s1(): 8 print 's1' 9 10 11 def s2(): 12 print 's2' 13 14 15 this_module = sys.modules[__name__] 16 17 hasattr(this_module, 's1') 18 getattr(this_module, 's2')
类也是对象
class Foo(object): staticField = "old boy" def __init__(self): self.name = 'wupeiqi' def func(self): return 'func' @staticmethod def bar(): return 'bar' print getattr(Foo, 'staticField') print getattr(Foo, 'func') print getattr(Foo, 'bar')
模块也是对象
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 def dev(): 5 return 'dev'
#!/usr/bin/env python # -*- coding:utf-8 -*- """ 程序目录: home.py index.py 当前文件: index.py """ import s2 as obj #obj.dev() func = getattr(obj, 'dev') func()