Python全栈之路系列之反射

作者: 2890bd62c72a | 来源:发表于2019-10-09 16:07 被阅读0次

    反射的定义

    根据字符串的形式去某个对象中操作成员

    1. 根据字符串的形式去一个对象中寻找成员
    2. 根据字符串的形式去一个对象中设置成员
    3. 根据字符串的形式去一个对象中删除成员
    4. 根据字符串的形式去一个对象中判断成员是否存在

    初始反射

    通过字符串的形式,导入模块

    根据用户输入的模块名称,导入对应的模块并执行模块中的方法

    在学习过程中有什么不懂得可以加我的
    python学习交流扣扣qun,784758214
    群里有不错的学习视频教程、开发工具与电子书籍。
    与你分享python企业当下人才需求及怎么从零基础学习好python,和学习什么内容
    # Python使用的是3.5.1
    [root@ansheng ~]# python -V
    Python 3.5.1
    # commons.py为模块文件
    [root@ansheng ~]# ls
    commons.py  reflection.py
    # commons.py文件内容
    [root@ansheng ~]# cat commons.py 
    #!/usr/bin/env python
    # 定义了连个函数,f1和f2
    def f1():
        return "F1"
    
    def f2():
        return "F2"
    [root@ansheng ~]# cat reflection.py 
    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    # 输入模块的名称
    mod_name = input("请输入模块名称>>> ")
    # 查看输入的内容及数据类型
    print(mod_name, type(mod_name))
    # 通过__import__的方式导入模块,并赋值给dd
    dd = __import__(mod_name)
    # 执行f1()函数
    ret = dd.f1()
    # 输出函数的返回值
    print(ret)
    # 执行reflection.py 
    [root@ansheng ~]# python reflection.py 
    # 输入模块名称
    请输入模块名称>>> commons
    # 返回输入的内容及数据类型
    commons <class 'str'>
    # 执行F1函数
    F1
    

    通过字符串的形式,去模块中寻找指定函数,并执行

    用户输入模块名称和函数名称,执行指定模块内的函数or方法

    [root@ansheng ~]# cat commons.py 
    #!/usr/bin/env python
    
    def f1():
        return "F1"
    
    def f2():
        return "F2"
    [root@ansheng ~]# cat reflection.py 
    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    
    # 输入模块的名称
    mod_name = input("请输入模块名称>>>")
    
    # 输入函数or方法的名称
    func_name = input("请输入函数名称>>>")
    
    # 导入模块
    dd = __import__(mod_name)
    
    # 导入模块中的方法
    target_func = getattr(dd, func_name)
    
    # 查看target_func和dd.f1的内存地址
    print(id(target_func), id(dd.f1))
    
    # 执行target_func()函数
    result = target_func()
    
    # 输出结果
    print(result)
    [root@ansheng ~]# python reflection.py
    # 输入模块名称commons
    请输入模块名称>>>commons
    # 输入函数名称f1
    请输入函数名称>>>f1
    # 返回内存地址
    139844714989224 139844714989224
    # 执行的函数返回结果
    F1
    

    反射相关的函数

    getattr(object, name[, default])

    根据字符串的形式去一个对象中寻找成员

    # 自定义模块的内容
    [root@ansheng ~]# cat commons.py 
    #!/usr/bin/env python
    
    Blog_Url = "https://blog.ansheng.me"
    
    def f1():
        return "F1"
    
    def f2():
        return "F2"
    
    >>> import commons
    >>> getattr(commons, "f1")
    <function f1 at 0x7fbce5774598>
    >>> getattr(commons, "f1f1f1")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: module 'commons' has no attribute 'f1f1f1'
    

    执行获取到的函数

    >>> target_func = getattr(commons, "f1")
    >>> target_func
    <function f1 at 0x7fbce5774598>
    >>> target_func() 
    'F1'
    

    通过设置默认值可以避免获取不到方法时报错

    # 设置一个默认值为None
    >>> target_func = getattr(commons, "f1f1f1", None)
    >>> target_func
    >>> 
    

    通过getattr获取模块中的全局变量

    >>> import commons
    >>> getattr(commons, "Blog_Url", None)
    'https://blog.ansheng.me'
    
    • setattr(object, name, value)

    根据字符串的形式去一个对象中设置成员

    设置全局变量

    # 获取commons内的Name变量
    >>> getattr(commons, "Name", None)
    # 在commons模块中设置一个全局变量Name,值为Ansheng
    >>> setattr(commons, "Name", "Ansheng")
    # 获取commons内的Name变量
    >>> getattr(commons, "Name", None)
    'Ansheng'
    

    getattr结合lambda表达式设置一个函数

    >>> setattr(commons, "as", lambda : print("as"))
    >>> getattr(commons, "as")
    <function <lambda> at 0x000001FD3E51FD90>
    >>> aa = getattr(commons, "as")
    >>> aa()
    as
    
    • delattr(object, name)

    根据字符串的形式去一个对象中删除成员

    >>> getattr(commons, "Name")
    'Ansheng'
    >>> delattr(commons, "Name")
    # 获取不到就报错
    >>> getattr(commons, "Name")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: module 'commons' has no attribute 'Name'
    

    hasattr(object, name)

    根据字符串的形式去一个对象中判断成员是否存在

    # 如果不存在就返回False
    >>> hasattr(commons, "Name")
    False
    >>> setattr(commons, "Name", "Ansheng")
    # 如果存在就返回True
    >>> hasattr(commons, "Name")
    True
    

    (双下划线)import(双下划线)方式导入多层模块

    >>> m = __import__("lib.commons")     
    >>> m
    # 返回的路径是`lib`
    <module 'lib' (namespace)>
    >>> m = __import__("lib.commons", fromlist=True)
    >>> m
    # 返回的路径是`lib.commons`
    <module 'lib.commons' from '/root/lib/commons.py'>
    

    基于反射模拟Web框架路由系统

    find_index.py文件内容

    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    
    url = input("请输入url: ")
    target_module, target_func = url.split('/')
    
    m = __import__("lib." + target_module, fromlist=True)
    
    if hasattr(m, target_func):
        target_func = getattr(m, target_func)
        r = target_func()
        print(r)
    else:
        print("404")
    

    目录结构及文件内容

    [root@ansheng ~]# tree ./
    ./
    ├── find_index.py
    └── lib
        ├── account.py
        └── commons.py
    
    1 directory, 3 files
    [root@ansheng ~]# cat lib/commons.py 
    #!/usr/bin/env python
    
    Blog_Url = "https://blog.ansheng.me"
    
    def f1():
        return "F1"
    
    def f2():
        return "F2"
    [root@ansheng ~]# cat lib/account.py 
    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    
    def login():
        return "login"
    
    def logout():
        return "logout"
    

    如果你依然在编程的世界里迷茫,可以加入我们的Python学习扣qun:784758214,看看前辈们是如何学习的!交流经验!自己是一名高级python开发工程师,从基础的python脚本到web开发、爬虫、django、数据挖掘等,零基础到项目实战的资料都有整理。送给每一位python的小伙伴!分享一些学习的方法和需要注意的小细节,点击加入我们的 python学习者聚集地

    执行

    [root@ansheng ~]# python find_index.py 
    请输入url: account/login
    login
    [root@ansheng ~]# python find_index.py 
    请输入url: account/logout
    logout
    [root@ansheng ~]# python find_index.py 
    请输入url: commons/f1
    F1
    [root@ansheng ~]# python find_index.py 
    请输入url: commons/f2
    F2
    [root@ansheng ~]# python find_index.py 
    请输入url: commons/asdasd
    404
    

    相关文章

      网友评论

        本文标题:Python全栈之路系列之反射

        本文链接:https://www.haomeiwen.com/subject/qhizjctx.html