Java是一門面向對象的語言。 每個Class,能夠有instance,能夠有Class對象。Instance的做用是調用方法、獲取屬性的,而Class對象則是獲取類有哪些屬性、方法的。Class對象與instance結合,也能夠完成對instance方法的調用等。Java中的絕大部分框架,都離不開發射。那麼在Python中,是否也有相似機制呢?html
1、根據instance獲取Class對象python
對於一個Class的instance,想要獲取所屬Class對象,能夠這樣:instance.__class__。 該方式也只是用於 Class。對於不是Class的instance的狀況下,若是獲取到它們的所屬類型呢?編程
2、使用type(obj)獲取某個對象的類型數組
該函數用於獲取任意一個Python對象的類型。app
參數框架 |
返回值函數 |
XxxClass instance工具 |
<class ‘XxxClass’>測試 |
XxxClass objectui |
<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編程的強大助手。而這些功能大多數就是由上面的那些函數組合完成的。