• python--5、模块


    模块

    程序的代码根据作用分散写入多个文件,这些文件相互引用,以实现程序的功能,这些文件即称之为”模块“。
    自己定义的函数或者变量为了防止在解释器中执行完退出后丢失,需要把代码写到文件中,再直接执行,称为“脚本”。
    但是程序在功能越来越多后,为了便于管理代码,通常将一个程序分为多个文件,这样使得程序结构更加清晰,也方便管理。这样就可以吧他们当做模块来导入到其他的模块中。实现了功能复用。
    同理,我们也可以拿来别人写好的模块来导入到自己的项目中使用,以提升开发效率。

    一个模块即包含Python定义和声明的文件,模块一般用于导入使用。

    import 可以加载的模块有:

    • Python编写的.py文件
    • 已被变异为共享库或DLL的C或C++扩展
    • 吧一系列模块组织到一起的文件夹(包的概念在之后介绍)
    • 使用C编写并链接到Python解释器的内置模块。

    示例:

    #test.py
    print('this is test')
    number = 123
    def ins1():
        print('test模块',number)
    def ins2():
        print('test模块')
        ins1()
    def ins3():
        global number
        number = 0

    import

    模块可以包含可执行的语句和函数的定义,为了初始化模块。他们在模块第一次被import导入时执行(即使在同一模块在一个程序中import了很多次,只有第一次导入时将模块加载到内存,后续的import只会引用)

    注:我们可以从sys.module中找到当前已经加载的模块,sys.module是一个字典,内部包含模块名与模块对象的映射,该字典决定了导入模块时是否需要重新导入。

    import导入过程

    为相应模块创建新的名称空间, 在新创建的命名空间中执行模块中包含的代码,创建模块名来引用该名称空间。

    • 在整个导入模块时,被导入模块有独立的名称空间

    被导入的每个模块都是一个独立的名称空间,定义在模块中的函数把这个模块当作全局名称空间,可防止模块的全局变量与调用它的文件的全局变量冲突。

    • 为模块起别名
    import test as tt
    print(tt.money)

    例如两个相似的模块有两个的功能一样的方法。根据用户输入判定该是哪个模块,再给这个模块起成特定的别名。

    • 在一行导入多个模块
    import module1,module2,……

    from module_name import func

    与import的对比

    • from .. import ..,是将模块中的方法名字直接导入到当前的名称空间中,so,在当前文件名称空间中,直接使用名字即可。
      若导入的模块方法中还需回掉原来模块的别的方法or变量,则还是以原模块中的为准。
      若是导入的模块方法直接与现文件中的方法冲突,则导入进来的会被覆盖掉。
    • 也支持as,对导入的方法做别名。
    • 也支持","导入多个

    from .. import *

    把模块中非"_"下划线开头的名字都导入到当前位置。
    这个可以使用__all__来控制*导入的方法。
    #__all__=['money','read1'] #这样在另外一个文件中用from spam import *就这能导入列表中规定的两个名字

    模块的重载(不重要)

    模块被导入后,被放到sys.module的字典中。若改变了模块内容,必须重启程序。python不支持重新加载或卸载之前导入的模块。
    哪怕在sys.module中删了模块对象,但仍有可能被其他程序组件引用。不会清掉。
    尤其是引用了这个模块中的一个类,用这个类产生了很多对象,因而这些对象都有关于这个模块的引用。

    两种python文件

    • 脚本:一个文件就是整个程序,用于被执行。
    • 模块:文件中存放着一堆功能,用于被导入使用。

    python内置的全局变量__name__

    • 当文件被当作脚本执行时:__name__ 等于 '__main__'
    • 当文件被当作模块导入时:__name__等于模块名

    用于控制.py文件在不同的应用场景下执行不同的逻辑。

    模块的搜索路径

    内存中已经加载的模块 -> 内置模块 -> sys.path路径中包含的模块。
    #我们自定义的模块名不应该与系统内置模块重名。

    可以通过修改sys.path来添加环境变量。

    import sys
    sys.path.append('/a/b/c')
    sys.path.insert(0,'/x/y/z')

    搜索环境变量时会在sys.path中从左往右找,sys.path中还可以包含.zip文件和.egg文件,python会把.zip文件当作一个目录取处理。

    #.egg文件是由setuptools创建的包,这是按照第三方python库和扩展时使用的一种常见格式,.egg文件实际上只是添加了额外元数据(如版本号,依赖项等)的.zip文件。

    #要强调的:只能从.zip文件中导入.py,.pyc等文件。使用C编写的共享库和扩展块无法直接从.zip文件中加载(此时setuptools等打包系统有时能提供一种规避方法),且从.zip中加载文件不会创建.pyc或者.pyo文件,因此一定要事先创建他们,来避免加载模块是性能下降。

    编译Python文件

    为了提高“加载模块的速度”,Python解释器会在__pycache__目录中缓存每个模块编译后版本,格式:module.version.pyc。保证了编译后的结果可多版本共存。
    #python检查源文件的修改时间与编译的版本进行对比,如果过期就需要重新编译,这是自动的过程。且编译的模块是平台独立的。所以相同的库可以在不同架构的系统之间共享,即pyc是一种跨平台的字节码,类似于JAVA .net。是由python虚拟机来执行的,但是pyc的内容跟python的版本相关,不同的版本编译后的pyc文件不同,2.5编译的Pyc文件不能到3.5上执行,并且pyc文件是可以反编译的。因而它的出现仅仅是用来提升模板的加载速度的,而不是用来加密

    python解释器在以下两种情况下不检测缓存

    #1 如果是在命令行中被直接导入模块,则按照这种方式,每次导入都会重新编译,并且不会存储编译后的结果(python3.3以前的版本应该是这样)
    python -m spam.py

    #2 如果源文件不存在,那么缓存的结果也不会被使用,如果想在没有源文件的情况下来使用编译后的结果,则编译后的结果必须在源目录下
    #注:

      • 模块名区分大小写,foo.py与FOO.py代表的是两个模块
      • 只有使用import语句是才将文件自动编译为.pyc文件,在命令行或标准输入中指定运行脚本则不会生成这类文件,因而我们可以使用compieall模块为一个目录中的所有模块创建.pyc文件
  • 相关阅读:
    python3图片转化成字符画
    ubuntu 18.04安装PIL(Python Imaging Library )
    Ubuntu 18.04安装钉钉
    django 使用iframe跨域请求
    django 自定义日志字段
    Ubuntu18.04下安装搜狗输入法(亲测有效)
    Nginx 配置指令手册
    js闭包Demo
    自己写了一个无缝滚动的插件(jQuery)
    写JQuery 插件 什么?你还不会写JQuery 插件
  • 原文地址:https://www.cnblogs.com/jinyudong/p/7703597.html
Copyright © 2020-2023  润新知