Fork me on GitHub

python3包与模块

高性能、封装性、可复用的代码考验逻辑能力和抽象能力

Python工程的组织结构:包、模块儿、类

  • 最顶级的组织结构:包(文件夹)
  • 第二个层级:模块(文件)
  • 第三个层级:类
  • 第四个层级:函数、变量(不属于组织结构,是类本身的特性)

Python包与模块的名字

区分不同包的同名模块:包名.模块名
形成的模块的路径叫做命名空间

一个包下面可以有子包,模块可以和包平级

普通文件夹想要变成包必须要有init.py文件
init.py本身也是一个模块,可以不写内容只是标注包
特殊地,init.py模块的名字就是包名

import导入模块

对于重复的定义需要从其他模块里引用。
利用 import 模块名 导入

1
2
3
4
5
6
#test1.c1
a = 1
#test1.c2
import c1
print(c1.a)

import导入的总是模块,需要用模块名.变量名的方法引用
可以用as简化书写

1
2
3
4
5
6
#test1.c1
a = 1
#test1.c2
import c1 as m
print(m.a)

优点是可以一眼看出属于哪个模块

from import 导入变量

1
2
3
#test1.c2
from c1 import a
print(a)

也可以from 包 import 模块
引用时用 模块.变量

引用大量变量时使用 * :

1
2
3
4
5
6
7
8
9
10
11
12
#test1.c1
a = 1
b = 2
c = 3
d = 4
#test1.c2
from c1 import *
print(a)
print(b)
print(c)
print(d)

控制*的行为:

1
2
3
4
5
6
7
8
9
10
11
12
#test1.c1
__all__ = ['a','c'] #用内置变量__all__来控制*的选择范围
a = 1
b = 2
c = 3
d = 4
#test1.c2
from c1 import *
print(a)
print(c)
print(d) #d没有被打印,报错

init.py 的用法

隐藏.pyc文件夹

paste image

代码换行:在上一行末尾加上\或者加上括号利用括号的特性换行

当包被导入时,init.py会首先自动被执行

1
2
3
4
5
6
7
8
#test1.__init__.py
a = 'This is a __init__.py file'
print(a)
#c8.py
import test1
#This is a __init__.py file

init.py的应用场景

1
2
3
4
5
6
7
8
9
10
11
#test1.__init__.py
__all__ = ['c1','c2'] #初始化*
#test1.__init__.py
import sys #批量导入库
import datetime
import io
#c8.py
import test1
print(test1.sys.path)

包与模块的几个常见错误

包和模块是不会被重复导入的,只会执行一次(入口文件的概念)
避免循环导入,不要形成闭环
导入模块的时候会执行模块里所有的代码

模块内置变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#test1.c3
infos = dir() //打印当前模块内所有变量
print(infos)
#['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
#test1.c4.py
'''
This is a c4 doc
'''
print('name:' + __name__)
print('package:' + __package__)
#print('doc:' + __doc__) #doc指的是模块的注释
print('file:' + __file__)
#c9.py
import test1.c4
#name:test1.c4
#package:test1
#doc:
# This is a c4 doc
#file:c:\Users\Tai Park\Documents\python\test1\c4.py

入口文件和普通模块内置变量的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#c9.py
'''
This is a c9 doc
'''
import test1.c4
print('_________________')
print('name:' + __name__)
print('package:' + (__package__ or '当前模块不属于任何包'))
print('doc:' + __doc__)
print('file:' + __file__)
name:test1.c4
package:test1
doc:
This is a c4 doc
#name:test1.c4
#package:test1
#doc:
# This is a c4 doc
#file:c:\Users\Tai Park\Documents\python\test1\c4.py
#_________________
#name:__main__ #入口文件中__name__会被强制修改为__main__
#package:当前模块不属于任何包
#doc:
# This is a c9 doc
#
#file:c9.py #入口文件中路径不同 ,和执行python命令所在目录是有关系的

name的经典应用

dir()可以打印当前所有变量,若不传参数显示所有,传参显示特定的变量

1
2
3
4
5
6
7
8
9
10
import sys
infos = dir(sys)
print(infos)
make a script both importable and executable:
if __name__ == '__main__':
print('This is app')
else:
print('This is a module')

cmd中 python -m 命名空间.模块 可以将其当作模块来运行
作为普通模块必须要有包,可执行文件没有包

相对导入和绝对导入 一

有一个主入口文件。
可执行文件和顶级包在同一级。
绝对导入:从顶级包开始往下导入
相对导入:. 当前目录 ..上级目录 …上上级目录

相对导入和绝对导入 二

相对导入不能超过顶级包。
入口不能用相对路径导入,相对路径根据name定位,而入口文件被强制改成了main所以不能使用。
若想在入口文件使用相对导入,用-m。

-------------本文结束 感谢您的阅读-------------
  • 本文标题: python3包与模块
  • 本文作者: 吴军旗
  • 本文链接: http://fanqieto.top/2018/07/14/python3包与模块/
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请保留原文链接及作者!
    • 欢迎搜索及关注:番茄技术小栈,所有文章都将同步在公众号上!
坚持原创技术分享,您的支持将鼓励我继续创作!