• python进阶之类的反射


    有应用场景的技术才是有灵魂的技术------>最近同时问我,在python中,给你一个函数或者类的字符串名称,你怎么得到该函数和类,以下结合源码记录我得到的方式:

    1.给一个函数的字符串"function"得到函数并运行

    class TestA(object):
        def get_test(self):
            print("我是函数1")
    
        def instance(self):
            print("我是函数2")
    
    
    ins = TestA()
    get_test = getattr(ins, "get_test")
    get_test()

    我们运行得到结果

    C:Users37521Anaconda2python.exe C:/mine/company1/new_media_backend/newmediaBE/wechat-public/public/app/api_1_0/test.py
    我是函数1
    
    Process finished with exit code 0

    通过python的反射方法getattr达到我们想要的结果,然后我们getattr函数的源码

    def getattr(object, name, default=None): # known special case of getattr
        """
        getattr(object, name[, default]) -> value
        
        Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
        When a default argument is given, it is returned when the attribute doesn't
        exist; without it, an exception is raised in that case.
        """
        pass

    根据源码解释getattr函数需要我们传一个对象,和一个字符串,然后从对象中找到和字符串同名的方法属性。

    当然跟getattr对应的反射方法为,setattr和delattr,顾名思义这里不多解释。

    2.第二个方法为eval函数

    class TestA(object):
        def get_test(self):
            print("我是函数1")
    
        def instance(self):
            print("我是函数2")
    
        @staticmethod
        def test3():
            print("我是静态方法")
    
    
    ins = TestA()
    get_test = getattr(ins, "get_test")
    get_test()
    print("-----------------1-------------------")
    instance = getattr(TestA, "instance")
    instance(ins)
    print("---------------2---------------------")
    eval("instance")(ins)
    print("-----------------3-------------------")
    eval("TestA").test3()

    我们在2处我们给eval函数传入一个instance函数字符串然后运行传出ins实例,在3出我们给eval函数传入TestA类字符串,然后运行类下的静态方法,我们看运行的结果如下

    C:Users37521Anaconda2python.exe C:/mine/company1/new_media_backend/newmediaBE/wechat-public/public/app/api_1_0/test.py
    我是函数1
    -----------------1-------------------
    我是函数2
    ---------------2---------------------
    我是函数2
    -----------------3-------------------
    我是静态方法
    
    Process finished with exit code 0

    得到我们想要的结果,那我们就好奇eval函数是怎么实现可以传入一个字符串就去寻找对应的函数或者类对象,我们看一下eval函数的源码

    def eval(source, globals=None, locals=None): # real signature unknown; restored from __doc__
        """
        eval(source[, globals[, locals]]) -> value
        
        Evaluate the source in the context of globals and locals.
        The source may be a string representing a Python expression
        or a code object as returned by compile().
        The globals must be a dictionary and locals can be any mapping,
        defaulting to the current globals and locals.
        If only globals is given, locals defaults to it.
        """
        pass

    我们根据源码解释,首先解释器会我们传入的去locals和globals中去找我们传入的source为键找对应的值,如果未传入globals和locals就会去默认的glocals和locals中寻找,然后我们就好奇这个globals和locals是什么,然后我们运行一下

    def globals(): # real signature unknown; restored from __doc__
        """
        globals() -> dictionary
        
        Return the dictionary containing the current scope's global variables.
        """
        return {}
    
    def locals(): # real signature unknown; restored from __doc__
        """
        locals() -> dictionary
        
        Update and return a dictionary containing the current scope's local variables.
        """
        return {}

    看源码解释,globals为返回一个包含全局变量的字典,locals为返回一个包含本地变量的字典,然后运行这两个函数,看一下结果:

    class TestA(object):
        a=1
        def get_test(self):
            print("我是函数1")
    
        def instance(self):
            print("我是函数2")
    
        @staticmethod
        def test3():
            print("我是静态方法")
    
    def b():
        print(222)
    
    print(globals())
    print(locals())
    
    结果:
    {'b': <function b at 0x0000000002F46978>, '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'C:/mine/company1/new_media_backend/newmediaBE/wechat-public/public/app/api_1_0/test.py', '__package__': None, 'TestA': <class '__main__.TestA'>, '__name__': '__main__', '__doc__': None}
    {'b': <function b at 0x0000000002F46978>, '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'C:/mine/company1/new_media_backend/newmediaBE/wechat-public/public/app/api_1_0/test.py', '__package__': None, 'TestA': <class '__main__.TestA'>, '__name__': '__main__', '__doc__': None}

    3.根据上打印的globals函数的结果,那我们也想到根源的获取类对象的方法

    globals()函数运行的结果为一个字典,类对象的字符串为建,类对象为值,所以我们可以这样得到:

    class TestA(object):
        a=1
        def get_test(self):
            print("我是函数1")
    
        def instance(self):
            print("我是函数2")
    
        @staticmethod
        def test3():
            print("我是静态方法")
    
    
    # print(globals())
    # print(locals())
    globals()["TestA"].test3()
    
    
    结果如下:
    C:Users37521Anaconda2python.exe C:/mine/company1/new_media_backend/newmediaBE/wechat-public/public/app/api_1_0/test.py
    我是静态方法
    
    Process finished with exit code 0
    globals()["TestA"].test3()通过字典操作得到类对象,在运行类下的静态方法。

    以上是我总结的3种,给出函数或类的字符串得到对应函数和类对象的方法,
    从前我一直抄袭别人的博客,现在我希望能反馈输出一些有用的原创,一直在路上
  • 相关阅读:
    Linux监控端口与性能分析的
    对大数据简单生态的部分认知随笔
    致敬那些年对nginx踩过的坑
    面试中一些比较尴尬的问题
    硬盘的接口有哪几种
    硬盘的逻辑结构
    Oracle数据库的备份与恢复还原笔记
    Linux安装Mysql5.7.29
    [转]为什么会有OPTION请求?
    图解HTTP(5-6章节)---阅后笔记
  • 原文地址:https://www.cnblogs.com/lifei01/p/12044407.html
Copyright © 2020-2023  润新知