好久没写新东西了,自从当了tm后,事情变得更多,没那么多时间来进行总结,刚测试完一个模块,弄了下python的反射,这里来总结一下。
python的反射比较类似于java的rtti(runtime type information),也就是所谓的运行时类型识别。
这里先举个例子:
#!/usr/bin/python
# -*- coding:utf-8 -*-
class person:
def __init__(self, pet):
self.pet = pet
def feedPet(self):
petType = getattr(self.pet, 'name')
if petType == "cat":
print "give it fish"
if petType == "dog":
print "give it bone"
class cat:
def __init__(self):
self.name = "cat"
class dog:
def __init__(self):
self.name = "dog"
def test():
aDog = dog()
aPerson = person(aDog)
aPerson.feedPet()
aCat = cat()
bPerson = person(aCat)
bPerson.feedPet()
if __name__ == "__main__":
test()
这个例子比较简单,一个person对象会根据pet对象的name属性来决定做什么操作。
有时候我们需要根据传入参数的类型来执行一些操作,或者判断下是否包含一些属性来执行一些操作,这个时候你可能就需要用到反射。
反射涉及到的一些方法:
1.dir
在python中,dir方法可以获取到该对象的所有属性对象,例如上面的例子中,如果在person对象中执行dir(self),那么就会打印['__doc__', '__init__', '__module__', 'feedPet', 'pet'],可以看到有feedPet和pet两个属性,其中feedPet是方法,pet是属性
这里补充一个例子:
ob1 = getattr(aPerson, 'feedPet')
ob1()
用这个方式可以调用aPerson对象的feedPet方法
2.getattr,setattr,hasattr
关于属性相关的主要会用到这几个方法,分别用来获取对象的属性值,设置对象的属性值,以及判断某对象是否存在某个属性,具体的用法比较简单,看下例子就可以了。
3.__import__
这个方法和import基本上是功能一致的,但是使用这个,就可以获取module对象,这样这个module下面的所有属性和方法就可以用了。
例如:
module = __import__('rtti')
ob = getattr(module, 'dog')()
可以用这种方法来实例化一个dog对象
4.type
type方法可以获取对象的类型,这个估计大家应该不陌生
还有一些高级用法,例如获取代码块,获取变量名之类的,感兴趣的话大家可以搜索一下。当然这个例子里的一些功能也可以用其他的方式来实现,但是遇到具体的问题的时候你可能就会意识到用反射来解决会比较方便。
5.如何获取本文件中的对象属性
通过globals方法获取
class A:
def __init__(self):
print "in A init"
def run(self):
print "in A run"
class B:
def __init__(self):
print "in B init"
def run(self):
print "in B run"
class C:
def __init__(self):
print "in C init"
def run(self):
print "in C run"
if __name__ == "__main__":
print globals()
globals()['A']()
输出: