标签:attribute   size   反射   ant   使用   报错   比较   返回   call   
python的对象反射功能,经常在编程时使用.相比较其它的编程语言使用非常方便.反射就是用字符串来操作对象或者类,模块中的成员.

一.对象的反射
反射功能的实现,由这4个内置函数来实现(hasattr, getattr, setattr, delattr)
1.1.hasattr判断是否有某个成员
判断对象中是否有属性, 方法.返回bool值
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
 
 | 
#!/usr/bin/env python 
# -*-coding:utf-8-*- 
  
class Foo(object): 
    country = "china" 
  
    def __init__(self, name): 
        self.name = name 
  
    def f(self): 
        print "function f" 
  
obj = Foo("abc") 
print hasattr(obj, "name")         #判断是否有name字段,返回True 
print hasattr(obj, "f")            #判断是否有f方法,返回True 
print hasattr(obj, "ok")           #没有这个方法,返回False 
print hasattr(obj, "country")      #判断有没有静态字段,返回True 
print hasattr(Foo, "country")      #使用类作为参数来判断 
print "class:", Foo.__dict__.keys() 
print "obj:", obj.__dict__.keys() 
 
 | 
 
 
上例中使用对象作为obj参数来判断,是否有类的静态方法.也是可以的.因为对象的特殊性,先在对象中找是否有该成员,如果没在,通过对象指针,在去创建这个对象的类中找查
执行结果
| 
 | 
True 
True 
False 
True 
True 
class: [‘__module__‘, ‘f‘, ‘country‘, ‘__dict__‘, ‘__weakref__‘, ‘__doc__‘, ‘__init__‘] 
obj: [‘name‘] 
 
 | 
 
 
 
 1.2.获取对象的成员
也可以使用对象来获取类的成员.和上例中的hasattr一样
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
 
 | 
#!/usr/bin/env python 
# -*-coding:utf-8-*- 
  
class Foo(object): 
    country = "china" 
  
    def __init__(self, name): 
        self.name = name 
  
    def f(self): 
        print "this is function = ", self.name 
obj = Foo("abc") 
print getattr(obj, "name")             #获取对象的name字段 
f = getattr(obj, "f")                  #通过对象获取类的方法 
print f                                #打印出来是信类的方法 
f()                                    #加上括号就能直接调用执行这个的方法 
print getattr(Foo, "country") 
print getattr(obj, "country")          #使用对象也能找到静态字段 
 
 | 
 
 
 
1.3.增加对象或者类的成员
动态的增加对象或者类中的成员
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
 
 | 
#!/usr/bin/env python 
# -*-coding:utf-8-*- 
  
class Foo(object): 
    country = "china" 
  
    def __init__(self, name): 
        self.name = name 
  
    def f(self): 
        print "this is function f.name = ", self.name 
  
  
obj = Foo("abc") 
setattr(obj, "age", 19)                       #增加普通字段 
setattr(obj, "show", lambda num: num +1)      #增加普通方法 
setattr(Foo, "tel", "+086")                   #增加静态字段 
print obj.age 
print Foo.tel 
print obj.show(10) 
 
 | 
 
 
执行结果
 
1.4.使用delattr动态的删除类或者方法成员
演示代码
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
 
 | 
#!/usr/bin/env python 
# -*-coding:utf-8-*- 
  
class Foo(object): 
    country = "china" 
  
    def __init__(self, name): 
        self.name = name 
  
    def f(self): 
        print "this is function f.name = ", self.name 
  
  
obj = Foo("abc") 
print getattr(obj, "name") 
delattr(obj, "name")                     #删除掉了对象的普通字段name 
print getattr(obj, "name") 
print getattr(Foo, "country") 
delattr(Foo, "country")                  #删除掉类的静态字段 
print getattr(Foo, "country")            #打印时说找不到些成员,报错 
 
 | 
 
 
执行结果
| 
 | 
Traceback (most recent call last): 
 File "D:/????/python/????????/day08/blog/fanshe.py", line 17, in <module> 
abc 
 print getattr(obj, "name") 
AttributeError: ‘Foo‘ object has no attribute ‘name‘ 
 
 | 
 
 
 
二.在当前模块中使用反射
获取到对应的模块.
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
 
 | 
#!/usr/bin/env python 
# -*-coding:utf-8-*- 
  
import sys 
  
data = "abc" 
def f1(): 
    print "f1 function" 
def f2(): 
    print "f2" 
  
this_module =  sys.modules[__name__] 
print hasattr(this_module, "data")             #使用反射 
f1_get = getattr(this_module, "f1")            #使用反射获取 
f1_get() 
 
 | 
 
 
 
以上是反射对类,对象,模块成员操作的基本方法.
 
三.使用字符串自动导入模块
依据传入的字符串,自动导入模块.类似上文的方法反射
| 
 | 
import importlib 
  
my_moudle_name = "lib.aa" 
aa = importlib.import_module(my_moudle_name) 
  
print(aa) 
print(aa.C().name) 
 
 | 
 
 
执行结果
| 
 | 
<module ‘lib.aa‘ from ‘D:\\python\\day10\\lib\\aa.py‘> 
ait24 
 
 | 
python对象反射和函数反射
标签:attribute   size   反射   ant   使用   报错   比较   返回   call   
原文地址:http://www.cnblogs.com/yanzi-meng/p/7930283.html