zoukankan      html  css  js  c++  java
  • Python 模块化 模块搜索顺序、重复导入、模块加载列表(五)


    模块搜索顺序、重复导入、模块加载列表

    0x00 模块搜索顺序:

    举例:

    #test.py
    import sys
    
    for p in sys.path:
    print(p)
    
    运行结果:
    C:python //pycharm环境中的Add content roots to PYTHONPATH
    C:python //脚本所在目录
    C:UsersihoneyAppDataLocalProgramsPythonPython35python35.zip //打包,java扎包,避免大量小文件占空间
    C:UsersihoneyAppDataLocalProgramsPythonPython35DLLs
    C:UsersihoneyAppDataLocalProgramsPythonPython35lib
    C:UsersihoneyAppDataLocalProgramsPythonPython35
    C:UsersihoneyAppDataLocalProgramsPythonPython35libsite-packages //第三方包安装路径
    C:UsersihoneyAppDataLocalProgramsPythonPython35libsite-packageswin32
    C:UsersihoneyAppDataLocalProgramsPythonPython35libsite-packageswin32lib
    C:UsersihoneyAppDataLocalProgramsPythonPython35libsite-packagesPythonwin
    

      

    模块的路径搜索顺序:
    程序主目录,脚本所在目录
    PYTHONPATH目录,包含python的path路径:标准库目录和第三方包目录

    环境变量:命令行敲的字符串,依次在路径中搜索

    当import 一个模块时,会依次的在以上路径顺序中查找,找到了就不再往后找了,找不到就导入异常,只搜索指定目录,不递归搜索。

    路径可以是字典、zip文件、egg文件(蟒蛇蛋)。
    .egg文件,是由setuptools库创建的包,添加了元数据(版本号、依赖项等)的zip文件。下一篇文章介绍。

    windows优先搜索".",即当前目录
    linux只会从环境变量中的路径中挨个找。

    比如,当我们在本地写了一个print.py时,windows下模块搜索顺序优先搜索当前目录,然后才是python的path路径 --> 标准库目录,由于当前目录下自定义了一个print模块,所以可能会导致其它模块print()打印异常


    0x01 模块的重复导入:

    1)创建以下三个文件:

    #test.py
    import test1
    import test2
    
    #test1.py
    print("this is test1 module")
    
    #test2.py
    print("this is test2 module")
    
    运行test.py的结果:
    this is test1 module
    this is test2 module
    

      

    2)修改下test.py:

    #test.py
    import test1
    import test2
    import test1
    
    再运行下查看结果:
    this is test1 module
    this is test2 module
    

      上面我们修改test.py后,导入了两次test1模块,但解释器并没有运行两次,也就是模块不会重复的导入。

    3)再修改下test.py和test1.py:

    #test.py
    import test2
    import test1
    
    #test1.py
    print("this is test1 module")
    import test2
    
    输出结果:
    this is test2 module
    this is test1 module
    

      这次我们先在test.py中先后导入了test2、test1模块,但从输出结果中看,test1.py中导入的test2模块也没有加载初始化,说明程序入口模块已经导入了某模块时,其它调用的模块也不会重复导入该模块。

    4)再修改如下:

    #test.py
    import test1
    print(test1.test2.x)
    
    #test1.py
    print("this is test1 module")
    import test2
    print(dir())
    
    #test2.py
    print("this is test2 module")
    x=444
    
    运行test.py结果:
    this is test1 module
    this is test2 module
    ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'test2']
    444
    

      这次依然可以通过test1.test2.x的方式访问test2模块中的x属性。

    总结:

    内存编址
    共享物理内存

    0x02 模块加载列表:

    import sys
    print(sys.modules.keys()) //加载的所有模块名
    
    dict_keys(['_codecs_cn', '_imp', 'stat', 'encodings.gbk', 'builtins', 'winreg', '_codecs', '__main__', '_sitebuiltins', '_warnings', 'encodings.latin_1', 'sysconfig', 'genericpath', 'errno', '_multibytecodec', 'encodings.utf_8', 'codecs', 'os', '_weakrefset', '_bootlocale', 'sys', 'os.path', 'encodings.aliases', '_collections_abc', 'encodings', 'ntpath', '_stat', '_frozen_importlib', 'site', 'abc', '_io', '_thread', 'test2', 'encodings.mbcs', 'nt', '_frozen_importlib_external', '_signal', '_weakref', '_locale', 'zipimport', 'io', 'marshal', 'test1'])
    

      其中部分模块及模块指向的位置:

    '__main__': <module '__main__' from 'C:/python/test.py'>,
    os.path <module 'ntpath' from 'C:\Users\ihoney\AppData\Local\Programs\Python\Python35\lib\ntpath.py'>
    sysconfig <module 'sysconfig' from 'C:\Users\ihoney\AppData\Local\Programs\Python\Python35\lib\sysconfig.py'>
    sys <module 'sys' (built-in)>
    os <module 'os' from 'C:\Users\ihoney\AppData\Local\Programs\Python\Python35\lib\os.py'>
    zipimport <module 'zipimport' (built-in)>
    test2 <module 'test2' from 'C:\python\test2.py'>
    ....
    

      其中部分模块是导入sys模块时,sys模块调用的模块,其中的'__main__'模块指向的是当前脚本名。

  • 相关阅读:
    小程序开发点滴积累
    使用openssl在windows 10下本地xampp配置https开发环境
    linux networking
    CGI,FastCGI,PHP-FPM,PHP-CLI,modPHP
    centos 7.2 64位 docker安装lamp环境
    反模拟类游戏外挂 转
    鼠标 hook 源码 C#版
    C# 鼠标连击源码 转
    win32 API 在win10 64位失效
    利用浏览器外部协议(URL Procotol)打开本地exe文件
  • 原文地址:https://www.cnblogs.com/i-honey/p/8034160.html
Copyright © 2011-2022 走看看