• 模块与包的使用

    模块的基础

    模块:一堆函数的集合体

    自第一模块:如果你自己写一个py文件,在文件内写入一堆函数,则它被称为自定义模块,即使用python编写的.py文件

    第三方模块:已被编译为共享库或DLL的C或C++扩展

    内置模块:使用C编写并链接到python解释器的内置模块

    包:把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包)

    import与from...import

    import首次导入模块发生了3件事:

    1. 以模块为准创造一个模块的名称空间
    2. 执行模块对应的文件,将执行过程中产生的名字都丢到模块的名称空间
    3. 在当前执行文件中拿到一个模块名

    模块的重复导入会直接饮用之前创造好的结果,不会重复执行模块的文件,即重复导入会发生:spam=spam=模块名称空间的内存地

    import spam, time, os
    
    # 推荐使用下述方式
    import spam
    import time
    import os
    

    from...import...首次导入模块发生了3件事:

    1. 以模块为准创造一个模块的名称空间
    2. 执行模块对应的文件,将执行过程中产生的名字都丢到模块的名称空间
    3. 在当前执行文件的名称空间中拿到一个名字,该名字直接指向模块中的某一个名字,意味着可以不用加任何前缀而直接使用
    • 优点:不用加前缀,代码更加精简
    • 缺点:容易与当前执行文件中名称空间中的名字冲突
    # spam.py
    
    __all__ = ['money', 'read1']  # 只允许导入'money'和'read1'
    
    # run.py
    from spam import *  # 导入spam.py内的所有功能,但会受限制于__all__
    

    import和from...import...的异同

    相同点:

    1. 两者都会执行模块对应的文件,两者都会产生模块的名称空间
    2. 两者调用功能时,需要跑到定义时寻找作用域关系,与调用位置无关

    不同点

    1. import需要加前缀;from...import...不需要加前缀

    循环导入问题

    解决方案

    我们可以使用函数定义阶段只识别语法的特性解决循环导入的问题,我们也可以从本质上解决循环导入的问题,但是最好的解决方法是不要出现循环导入。

    # m1.py
    print('from m1.py')
    
    
    def func1():
        from m2 import x
        print(x)
    
    
    y = 'm1'
    
    # m1.py
    print('from m1.py')
    
    
    y = 'm1'
    from m2 import x
    

    python文件的两种用途

    python文件总共有两种用途,一种是执行文件;另一种是被当做模块导入。

    编写好的一个python文件可以有两种用途:

    1. 脚本,一个文件就是整个程序,用来被执行
    2. 模块,文件中存放着一堆功能,用来被导入使用
    # aaa.py
    
    x = 1
    
    
    def f1():
        print('from f1')
    
    
    def f2():
        print('from f2')
    
    
    f1()
    f2()
    
    # run.py
    
    import aaa
    

    如果直接运行run.py会直接运行aaa.py中的f1()f2(),但是如果我们在aaa.py中加上if __name__ == '__main__':这句话,则可以防止运行run.py时执行f1()f2()。因为当aaa.py被直接执行,即当做执行文件的时候__name__ == '__main__'; 在aaa.py被当做模块直接运行的时候__name__ == 'aaa'。由此可以让aaa.py在不同的场景下有着不同的用法。

    # aaa.py
    
    x = 1
    
    
    def f1():
        print('from f1')
    
    
    def f2():
        print('from f2')
    
    
    if __name__ == '__main__':
        f1()
        f2()
    

    包是模块的一种形式,包的本质就是一个含有__init__.py的文件夹。

    模块与包

    导入模块发生的三件事:

    1. 创建一个包的名称空间
    2. 执行py文件,将执行过程中产生的名字存放于名称空间中。
    3. 在当前执行文件中拿到一个名字aaa,aaa是指向包的名称空间的

    导入包发生的三件事:

    1. 创建一个包的名称空间
    2. 由于包是一个文件夹,无法执行包,因此执行包下的__init__.py文件,将执行过程中产生的名字存放于包名称空间中(即包名称空间中存放的名字都是来自于__init__.py)
    3. 在当前执行文件中拿到一个名字aaa,aaa是指向包的名称空间的

    导入包就是在导入包下的__init__.py,并且可以使用以下两种方式导入:

    1. import ...
    2. from ... import...

    注意事项

    包内所有的文件都是被导入使用的,而不是被直接运行的

    包内部模块之间的导入可以使用绝对导入(以包的根目录为基准)与相对导入(以当前被导入的模块所在的目录为基准),推荐使用相对导入

    当文件是执行文件时,无法在该文件内用相对导入的语法,只有在文件时被当作模块导入时,该文件内才能使用相对导入的语法

    凡是在导入时带点的,点的左边都必须是一个包,import aaa.bbb.m3.f3错误

  • 相关阅读:
    TypeScript & JSDoc All In One
    k8s & Docker All In One
    How to custom your own Node.js Docker Image All In One
    rollup & TypeScript & tslib All In One
    Linux file system All In One
    how to use npm delete one history version package All In One
    How to use Web Components in React or Vue All In One
    看了这篇使用 dist 发布 npm 包的文章,我整个人都栓Q 了
    yarn 1.x & yarn 2.x All In One
    python中删除字符串中的指定字符
  • 原文地址:https://www.cnblogs.com/1naonao/p/10994586.html
Copyright © 2020-2023  润新知