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’>

 

3isinstance(obj, class)

  可以用isinstance(obj, class)来判断实例与class的关系。如果返回True,代表obj是 class或者其子类的实例。

  在Python中,一切都是对象,例如package,module,class,function,instance都是对象。在上面使用type可以获取判定是哪种类型的,但是如果我们程序中只是想要判定一个对象是否是哪种类型的,使用type并不方便。而使用isinstance则可以快速判定了。

例如:

  1. import types
  2. isinstance(obj, types.ModuleType) # 判定是否是module
  3. isinstance(obj, (types.ClassType,types.TypeType)) #判定是类

 

4、利用反射来获取属性、调用方法

  利用反射来访问instance的属性,方法,前提是已知instance、要访问的属性或者方法的名称(name)。在Python中,这一切就变得简单了,通过内置函数getattr(obj,name) 就可以获取到一个Python对象任意属性方法。如果要获取一个属性,获取的就是属性值;如果要获取方法,获取到的是方法对象。要获取的方法、属性,如果没有会从父类找的。

 

  就拿之前的一个例子来说明问题:

 

  1. #!python
  2. #-*- coding: utf-8 -*-
  3.  
  4. class Person(object):
  5. id=''
  6. name = ''
  7. age = 3
  8. # 等同于Java中的<init>,即构造器
  9. def __init__(self, id, name, age):
  10. print("init a Person instance")
  11. self.id = id
  12. self.name = name
  13. self.age = age
  14. def show(this):
  15. print(this)
  16. # print(this.toString())
  17.  
  18. # def toString(self):
  19. # return "id:{}, name:{}, age:{}".format(self.id, self.name, self.age)
  20. # 等同于Java中的toString
  21. def __str__(self):
  22. # return self.toString()
  23. return "id:{}, name:{}, age:{}".format(self.id, self.name, self.age)
  24. # 等同于Java中的finalize方法,del 实例时调用
  25. def __del__(self):
  26. print("finally a Person instance")
  27. self.id = None
  28. self.name = None
  29. self.age = None
  30. self = None
  31. def __get__(self, name):
  32. print("invoke in __get__")
  33. print(self.__dict__)
  34. return 1111
  35.  
  36. def __getattr__(self, name):
  37. print("invoke in __getattr__")
  38. return 1111
  39. '''
  40. def __getattribute__(self, name):
  41. print("invoke in __getattribute__")
  42. print(object.__getattribute__(self, name))
  43. print("after invoke in __getattribute__")
  44. return object.__getattribute__(self, name)
  45. '''
  46.  
  47. class Student(Person):
  48. def __init__(self, id, name, age,email):
  49. print("invoke in Student __init__")
  50. super(Student, self).__init__(id, name, age) # invoke Person#__init__
  51. self.email = email
  52. def __getitem__(self, name):
  53. return self.__dict__[name] + "_suffix"
  54.  
  55.  
  56. def show(self):
  57. print("show in ......")
  58. print("__dict__:{}".format(self.__dict__))
  59. print("__class__:{}".format(self.__class__))
  60. print("isinstance(self, __class__):{}".format(isinstance(self, self.__class__)))
  61. print("type:{}".format(type(self)))
  62. print("show out ......")
  63. @staticmethod
  64. def s_show(o):
  65. o.show();

下面是反射测试: 

  1. #!python
  2. #-*- coding: utf-8 -*-
  3.  
  4. '''
  5. from model import Person
  6. print(dir(Person))
  7. p1 = Person('0001', 'fjn', 20)
  8. print(p1)
  9. p1.show()
  10. print(p1.name)
  11. print(p1.xx)
  12. del p1
  13. '''
  14. import model
  15. Student = model.Student
  16. s = Student('0001', 'fjn', 20, 'fs1194361820@163.com')
  17. s.show()
  18. print(s["email"])
  19. '''
  20. print(type(model))
  21. print(type(Student))
  22. print(type(Student.show))
  23. print(type(Student.s_show))
  24. print(type(len))
  25. print(dir(Student))
  26. print(isinstance(type(Student),type))
  27. print(isinstance(type(model),type))
  28. '''
  29. showMethod = getattr(s,"show") #get show method object from object s
  30. if(showMethod!=None):
  31. #apply(showMethod) # use apply invoke show method
  32. showMethod() # invoke show method direct
  33.  
  34. print(getattr(s,"age"))
  35. import types
  36. print(isinstance(Student, (types.TypeType,types.ClassType)))
  37. print(isinstance(s, types.InstanceType))
  38. import inspect
  39. print(inspect.isclass(Student))

 


5
Python的反射工具:inspect 

  Python提供了一个inspect模块,它封装了上面的所有功能。官方文档参见:https://docs.python.org/2/library/inspect.html#。也可以通过pydoc来查看该模块。

  这个工具提供了对象类型判定,成员获取,源码位置,运行时Stack,异常trace等功能,应该成为Python编程的强大助手。而这些功能大多数就是由上面的那些函数组合完成的。

 

版权声明:本文为f1194361820原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/f1194361820/p/8721745.html