Python : 反射
Java是一门面向对象的语言。 每一个Class,可以有instance,可以有Class对象。Instance的作用是调用方法、获取属性的,而Class对象则是获取类有哪些属性、方法的。Class对象与instance结合,也可以完成对instance方法的调用等。Java中的绝大部分框架,都离不开发射。那么在Python中,是否也有类似机制呢?
1、根据instance获取Class对象
对于一个Class的instance,想要获取所属Class对象,可以这样:instance.__class__。 该方式也只是用于 Class。对于不是Class的instance的情况下,如果获取到它们的所属类型呢?
2、使用type(obj)获取某个对象的类型
该函数用于获取任意一个Python对象的类型。
参数 |
返回值 |
XxxClass instance |
<class ‘XxxClass’> |
XxxClass object |
<type ‘type’> |
XxxClass.instancemthod |
<type ‘instancemethod’> |
XxxClass.staticMethod |
<type ‘function’> |
XxxModule |
<type ‘module’> |
Len,min |
<type ‘builtin_function_or_method’> |
3、isinstance(obj, class)
可以用isinstance(obj, class)来判断实例与class的关系。如果返回True,代表obj是 class或者其子类的实例。
在Python中,一切都是对象,例如package,module,class,function,instance都是对象。在上面使用type可以获取判定是哪种类型的,但是如果我们程序中只是想要判定一个对象是否是哪种类型的,使用type并不方便。而使用isinstance则可以快速判定了。
例如:
import types isinstance(obj, types.ModuleType) # 判定是否是module isinstance(obj, (types.ClassType,types.TypeType)) #判定是类
4、利用反射来获取属性、调用方法
利用反射来访问instance的属性,方法,前提是已知instance、要访问的属性或者方法的名称(name)。在Python中,这一切就变得简单了,通过内置函数getattr(obj,name) 就可以获取到一个Python对象任意属性方法。如果要获取一个属性,获取的就是属性值;如果要获取方法,获取到的是方法对象。要获取的方法、属性,如果没有会从父类找的。
就拿之前的一个例子来说明问题:
#!python #-*- coding: utf-8 -*- class Person(object): id='' name = '' age = 3 # 等同于Java中的<init>,即构造器 def __init__(self, id, name, age): print("init a Person instance") self.id = id self.name = name self.age = age def show(this): print(this) # print(this.toString()) # def toString(self): # return "id:{}, name:{}, age:{}".format(self.id, self.name, self.age) # 等同于Java中的toString def __str__(self): # return self.toString() return "id:{}, name:{}, age:{}".format(self.id, self.name, self.age) # 等同于Java中的finalize方法,del 实例时调用 def __del__(self): print("finally a Person instance") self.id = None self.name = None self.age = None self = None def __get__(self, name): print("invoke in __get__") print(self.__dict__) return 1111 def __getattr__(self, name): print("invoke in __getattr__") return 1111 ''' def __getattribute__(self, name): print("invoke in __getattribute__") print(object.__getattribute__(self, name)) print("after invoke in __getattribute__") return object.__getattribute__(self, name) ''' class Student(Person): def __init__(self, id, name, age,email): print("invoke in Student __init__") super(Student, self).__init__(id, name, age) # invoke Person#__init__ self.email = email def __getitem__(self, name): return self.__dict__[name] + "_suffix" def show(self): print("show in ......") print("__dict__:{}".format(self.__dict__)) print("__class__:{}".format(self.__class__)) print("isinstance(self, __class__):{}".format(isinstance(self, self.__class__))) print("type:{}".format(type(self))) print("show out ......") @staticmethod def s_show(o): o.show();
下面是反射测试:
#!python #-*- coding: utf-8 -*- ''' from model import Person print(dir(Person)) p1 = Person('0001', 'fjn', 20) print(p1) p1.show() print(p1.name) print(p1.xx) del p1 ''' import model Student = model.Student s = Student('0001', 'fjn', 20, 'fs1194361820@163.com') s.show() print(s["email"]) ''' print(type(model)) print(type(Student)) print(type(Student.show)) print(type(Student.s_show)) print(type(len)) print(dir(Student)) print(isinstance(type(Student),type)) print(isinstance(type(model),type)) ''' showMethod = getattr(s,"show") #get show method object from object s if(showMethod!=None): #apply(showMethod) # use apply invoke show method showMethod() # invoke show method direct print(getattr(s,"age")) import types print(isinstance(Student, (types.TypeType,types.ClassType))) print(isinstance(s, types.InstanceType)) import inspect print(inspect.isclass(Student))
5、Python的反射工具:inspect
Python提供了一个inspect模块,它封装了上面的所有功能。官方文档参见:https://docs.python.org/2/library/inspect.html#。也可以通过pydoc来查看该模块。
这个工具提供了对象类型判定,成员获取,源码位置,运行时Stack,异常trace等功能,应该成为Python编程的强大助手。而这些功能大多数就是由上面的那些函数组合完成的。
作者: 房继诺
出处:http://www.cnblogs.com/f1194361820
版权:本文版权归作者和博客园共有
欢迎转载,转载请需要注明博客出处
技术交流QQ:1194361820,加好友请注明:来自博客园,不要说你是博客园,也可以扫描图像二维码直接加我。