• 知识点


        断断续续从年前到现在学了面向对象一个月了,之前学反射的时候,只是都是看下代码,理解就可以了,今天在代码的时候还是不太得心应手,于是百度各种,终于明白了,写此博客,供自省。

    反射

    1 什么是反射

    反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

    2 python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

    四个可以实现自省的函数 下列方法适用于类和对象(一切皆对象,类本身也是一个对象)

    看了定义,还是只是了解一下,不贴代码都是刷流氓,直接上代码。

    # test.py
    import sys
    def fn():
        print(‘hello world‘)
    
    func_name = fn.__name__
    fn_obj = getattr(sys.modules[__name__], func_name)
                # 根据函数名(func_name),获得函数对象
    fn_obj()

     运行结果是:

    hello world

    先大致看一下思路,

    1. 首先定义了一个fn的函数

    2. 通过获取当前__name__的值 来反射

    估计你也是看的云里雾里。接下来我一一解释。

    抛砖引玉

    对于__name__大家不知道理解不,上代码。

    #!/usr/bin/env python
    def test():
        print('hello world.')
        print("__name__ = ",__name__)
    
    if __name__ == '__main__':
        test()
    hdfs@loocha11:~$ cat test2.py 
    import test
    
    test.test()

    运行

    hdfs@loocha11:~$ python3 test.py 
    hello world.
    __name__ =  __main__
    hdfs@loocha11:~$ python3 test2.py 
    hello world.
    __name__ =  test

    从上可以看出,直接运行test的时候__name__就是等于字符串‘__main__’,要是被其他文件导入此时__name__就是等于模块名字。

    总结:

    当模块不是导入,而是直接运行,那么__name__的值就是__main__。理解__name__了吧。

    知识点:

    sys.modules是一个全局字典,该字典是python启动后就加载在内存中。
    每当程序员导入新的模块,sys.modules都将记录这些模块。
    字典sys.modules对于加载模块起到了缓冲的作用。
    当某个模块第一次导入,字典sys.modules将自动记录该模块。
    当第二次再导入该模块时,python会直接到字典中查找,从而加快了程序运行的速度。

    既然懂了__name__,接下来我们继续最初的代码一一分析。

    自省的函数 下列方法适用于类和对象(一切皆对象,类本身也是一个对象),先看其中两个。

    hasattr(object,name)

    判断object中有没有一个name字符串对应的方法或属性

    getattr(object, name, default=None)

    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
    # test.py
    import sys
    def fn():
        print(‘hello world‘)
    
    func_name = fn.__name__  # 
    fn_obj = getattr(sys.modules[__name__], func_name)
                # 根据函数名(func_name),获得函数对象
    fn_obj()

    分析

    1. 此时等于 func_name     等于    fn,
    
    2. __name__     等于    __main__
    
    3. sys.modules[__name__]   等于   sys.modules[test.py] #这个可能说不太妥当
    
    4. getattr(sys.modules[__name__], func_name) 也就是sys.modules[__name__] 中取fn方法对象。
    5. fn_obj() 表示 sys.modules[__name__] 中取fn方法实现也就是执行输出

    此时应该理解最初的代码了吧

  • 相关阅读:
    一步一步CCNA之二:路由器特权模式
    uncompress bz2
    Protothreads Lightweight, Stackless Threads in C
    sohu的正版美剧都挺不错的
    Ebot crawler
    大数据时代的创新者们
    technology company
    slogan
    娱乐新闻都怎么搞的,真不给力啊
    售楼小姐比较漂亮
  • 原文地址:https://www.cnblogs.com/caimengzhi/p/8487203.html
Copyright © 2020-2023  润新知