zoukankan      html  css  js  c++  java
  • 模块与包的使用

    模块的基础

    模块:一堆函数的集合体

    自第一模块:如果你自己写一个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错误

  • 相关阅读:
    判断的几种结构
    关于电脑的基础单词笔记
    JAVA插入数据笔记
    完全卸载oracle11g步骤
    hibernate框架
    Java中的字符串比较
    java集合 list与Set、Map区别
    向MyEclipse的项目中导入js文件时,出现小红叉
    Java基础面试题
    java面试题 -- JVM
  • 原文地址:https://www.cnblogs.com/1naonao/p/10994586.html
Copyright © 2011-2022 走看看