zoukankan      html  css  js  c++  java
  • 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’>

    3isinstance(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编程的强大助手。而这些功能大多数就是由上面的那些函数组合完成的。

  • 相关阅读:
    PHP配置文件处理类
    PHP中实现图片上传的类库
    在PHP中实现StringBuilder类
    微软官方及第三方SDK http://msdn.microsoft.com/zhcn/jj923044
    在PHP中模拟asp的response类
    Atitit.并发测试解决方案(2) 获取随机数据库记录 随机抽取数据 随机排序 原理and实现
    atitit. access token是什么??微信平台公众号开发access_token and Web session保持状态机制
    atitit.二进制数据无损转字符串网络传输
    atitit.重装系统需要备份的资料总结 o84..
    atitit.web ui 结构建模工具总结
  • 原文地址:https://www.cnblogs.com/f1194361820/p/8721745.html
Copyright © 2011-2022 走看看