python-包(Package)

88 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情


大家好,我是芒果,一名非科班的在校大学生。对C/C++、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流

作者简介:



理解 "导入" 和 "加载"

我们写 import module 时, 其实有两个大的阶段, 先将这个模块的文件加载到内存中, 并创建一个对象来表示; 然后通过一个变量名来将这个模块引入到当前的命名空间中.

如果同一个模块(例如sys这样的常用模块)被import了多次, 其实加载动作只进行了一次(也就是说内存中只有一份sys的代码), 执行动作也只进行了一次

import add
import add
#执行结果:
In Add函数内部

模块的内置变量

我们可以通过globals()函数看到全局命名空间下有几个内置变量

print(globals())
#执行结果:
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000026C824D6400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/Python文件存储/Class01.py', '__cached__': None}

其中:

builtins : 内建函数模块. 包含了open, help, doc等内建函数的定义 name : **模块名字. 如果是从这个模块开始执行, 那么 name 值为 main,否则就是当前文件不包含后缀的名称

入口文件是谁,__name就是__name

file : 模块的文件名 doc : 模块的文档字符串 package :模块从属的包名


回忆我们刚刚讲过的, import的时候, 会执行这个模块. 我们期望, 这个模块被别人导入时, 只进行函数定义; 如果直接从这个模块开始运行, 则在函数定义完成后再进行一些测试

例子:

'''
定义两数相加的函数
'''
def Add(x,y):
    return x+y
​
#测试:
if __name__ == '__main__':
    print(Add(1,2))
    print(Add(2,3))

判定 name 是否值为 main , 如果是的话, 说明是直接执行add.py, 这时候就执行测试代码. 否则 认为add是被其他Python文件import的, 不执行测试代码.

包(Package)

当我们代码量进一步变大时, 光拆分成多个文件已经不足以满足需求, 还需要能按照一定的目录结构层次化的组织这些模块. 同时包也可以解决模块之间的名字冲突问题.

目录也是包的一种 ,包也是模块

如:以下面的方式组织代码结构:

test.py
calc/
    add.py
    __init__.py

在calc目录中增加一个 init.py 文件, calc这个目录就成了包(Package). 可以在test.py文件中import calc中的模块了

init.py 是包的初始化文件, 会首先执行它


init.py 是在包加载的时候会进行执行, 负责一些包的初始化操作. 一般是空文件即可.


包中是可以嵌套其他的包的