• python基础之反射


    概述

    反射其实就是动态的加载模块,而不需要像之前的那样,需提前import各种模块的方式.

    hasattr,getattr

    同一目录下有两个文件:

    .
    |____commons.py
    |____impor.py
    

    commons.py内容:

    def login():
        print('login!!!')
    
    def logout():
        print('logout!!!!')
    
    def index():
        print('home page!!!')
    
    
    if __name__ == '__main__':
        login()
    

    impor.py文件中想调用commons模块里的函数,一般规则就是先import commons,然后得提前知道commons的已定义函数名称才能正常调用,否则报错

    那我们能否判断是否有函数名然后再调用其函数呢?看下例子:

    import commons
    
    res=hasattr(commons,'login')  #1
    print(res)
    
    res1=hasattr(commons,'loginxxx')
    print(res1)
    
    res2=getattr(commons,'login') #2
    print(res2) #3
    res2() #4
    

    输出结果:

    True
    False
    <function login at 0x10137b7b8>
    login!!!
    

    看出来了吧:

    1. 标志符#1中hasattr判断commons模块中是否有叫login函数的,注意是字符串字符串字符串,如果有是True,否则我False
    2. 标志符#2中getattr用来获取login函数的内存中的地址,注意函数名也为*字符串字符串字符串**
    3. 标识符#3,打印了res2的内存地址
    4. 后面加括号执行函数login()

    setarr:

    setattr(commons,'test','this is a test')
    res=getattr(commons,'test')
    print(res)
    

    out:

    this is a test
    

    delattr:

    import commons
    
    res=hasattr(commons,'login')
    print(res)
    delattr(commons,'login')
    res1=hasattr(commons,'login')
    print(res1)
    

    out:

    True
    False
    

    来总结下:

    函数 功能 用法注意事项
    hasattr 判断某模块是否有指定的模块 hasattr(aaa,'bbb'),其中aaa为模块名称,不带引号,bbb为函数名称,是字符串
    getattr 从模块中获取指定的模块 getattr(aaa,'bbb'),与hasattr用法相同
    setattr 在指定模块中设置模块 setattr(aaa,'bbb','ccc'),在模块aaa中设置一个叫bbb的函数或者变量,此变量名称叫ccc,注意字符串
    delattr 在模块中删除某函数 delattr(aaa,'bbb'),从aaa模块中删除bbb的函数,但对模块本身文件不会做修改

    这就是反射:利用字符串的形式去对象(模块)中操作(寻找/检查/删除/设置)成员

    动态加载模块

    python中使用了__import__的方法,可以动态的导入模块,实现反射的功能.import()可以根据参数导入指定的模块,参数可为字符串,也可为字符串赋值的变量,来个例子:

    m,f=['commons','login']
    obj=__import__(m,f)
    print(obj)
    

    out:

    <module 'commons' from '/Users/shane/PycharmProjects/Py_study/Base/s6/commons.py'>
    
    obj=__import__('commons','login')
    print(obj)
    

    out:

    <module 'commons' from '/Users/shane/PycharmProjects/Py_study/Base/s6/commons.py'>
    

    那么我们新写一个模块,来导入上面例子中commons模块吧:

    while True:
        inp=input('input the url:')
        m,f=inp.split('/')
        obj=__import__(m)
        print(obj)
        if hasattr(obj,f):
            func=getattr(obj,f)
            func()
        else:
            print('404!!')
    

    out:

    input the url:commons/login
    <module 'commons' from '/Users/shane/PycharmProjects/Py_study/Base/s6/commons.py'>
    login!!!
    input the url:commons/index
    <module 'commons' from '/Users/shane/PycharmProjects/Py_study/Base/s6/commons.py'>
    home page!!!
    input the url:commons/ddd
    <module 'commons' from '/Users/shane/PycharmProjects/Py_study/Base/s6/commons.py'>
    404!!
    

    效果还不错哇!!!

    这种方式,可以解决N多个模块的导入问题,模块最上面也不需要写辣么多import啦.

    不同目录的模块加载

    有个目录类似于下面:

    .
    |____page.py
    |____tester
    | |______pycache__
    | | |____commons.cpython-35.pyc
    | |____commons.py
    

    page.py 想调用tester中的commons模块,怎么搞?

    m,f=['commons','login']
    obj=__import__('tester.'+m)
    print(obj)
    res=hasattr(obj,f)
    result=getattr(obj,f)
    print(res)
    result()
    

    out:

    <module 'tester' (namespace)>
    Traceback (most recent call last):
      File "/Users/shane/PycharmProjects/Py_study/Base/test/page.py", line 26, in <module>
        result=getattr(obj,f)
    AttributeError: module 'tester' has no attribute 'login'
    

    测试下,加个fromlist=True:

    m,f=['commons','login']
    obj=__import__('tester.'+m,fromlist=True)
    print(obj)
    res=hasattr(obj,f)
    result=getattr(obj,f)
    print(res)
    result()
    

    out:

    <module 'tester.commons' from '/Users/shane/PycharmProjects/Py_study/Base/test/tester/commons.py'>
    True
    login!!!
    

    Binggo!!!!

    fromlist是一个允许从列表导入的功能,使用方式:import('xx.xx.xx.xx',fromlsit=True)

    看这个例子:

    obj=__import__('tester.commons',fromlist=True)
    print(obj)
    res=hasattr(obj,'login')
    print(res)
    

    out:

    
    <module 'tester.commons' from '/Users/shane/PycharmProjects/Py_study/Base/test/tester/commons.py'>
    True
    

    以上案例写完就是这个样子的:

    while True:
        inp=input('input the url:')
        m,f=inp.split('/')
        obj=__import__('tester.'+m,fromlist=True)
        if hasattr(obj,f):
            res=getattr(obj,f)
            res()
        else:print('404')
    

    out:

    input the url:commons/index
    home page!!!
    input the url:commons/login
    login!!!
    input the url:
    
  • 相关阅读:
    Collaborative Knowledge base Embedding (CKE)
    Multi-Task Feature Learning for Knowledge Graph Enhanced Recommendation(知识图谱)
    解决:install service error: InstallAsEventCreate() failed: xxx registry key already exists
    解决:“由于可能不会将凭据发送到远程计算机,因此将不会进行连接。若要获得协助,请与您的系统管理员联系”
    Asp.Net Core下使用swagger生成api文档
    .NET Core 发布(dotnet publish)
    【.net core 入坑】.net core 3.0 报错:在 FETCH 语句中选项 NEXT 的用法无效
    使用SC命令操作(安装、开启、配置、关闭、删除)Windows下的服务
    asp.net core web应用以windows服务的方式安装运行
    asp.net core 3.0获取web应用的根目录
  • 原文地址:https://www.cnblogs.com/ccorz/p/5587109.html
Copyright © 2020-2023  润新知