“Life is short, You need Python” – Bruce Eckel
Environment
“Python 自带电池”,指的就是 Python 标准库,它随着 Python 的安装被安装到了本地,其中包含了许多好用高效的内置模块们,如 os、pickle 等。
“You don’t have to reinvent the wheel.” Python 有大量的第三方库,如进行数据分析,常会用到 numpy、scipy、pandas 等包,有称呼 numpy 和 scipy 作科学计算库。此外,还有爬虫框架(scrapy等),深度学习框架(tensorflow、pytorch等),web应用框架(flask、django等)。
在日常使用中,不管是 模块 还是 包 还是 库或是框架,import
就完事了。但搞搞清楚区别还是要的。
/anaconda3/envs/环境名/lib/python3.7/
/anaconda3/envs/环境名/lib/python3.7/site-packages/
库(library) 强调的是功能性,表示完成一定功能的代码的集合,可以是一些模块的集合,如内置模块们来自 Python 标准库;可以是一个包,如numpy 和 scipy 又被称为科学计算库。区别于 Python 库,其他来源的库都可以称为为“第三方库”。
框架(framework) 是库的集合,提供解决问题的一整套方案。与 库 的不同之处在于,框架 存在较强的约束性,需要按照其中的规则办事,像是一门独立的语言。
import 模块名 [as 别名]
导入整个模块,可以在一行导入多个模块。通过 模块名或别名.函数名或变量名或类名
调用import random, math
random.seed(0)
print(random.randint(1, 3)) # 2
print(math.e) # 2.718281828459045
from 模块名 import 函数名或变量名或类名 [as 别名]
导入模块中特定的函数或变量或类,调用时可以省略模块名;拒绝使用 from 模块名 import *
导入模块中所有的方式。from random import randint
# 随机从 1 到 3 的整数中返回一个
res = randint(1, 3)
若导入的函数名(或变量名或类名)与已有的同名,将发生覆盖。可见,from 模块名 import *
更容易带来麻烦,因此别这么干。
e = 666
from math import e
print(e) # 2.718281828459045
关注两个属性,__name__、__doc__ 和 __all__
在 Python 执行文件中运行 __name__
print(__name__) # 输出 __main__
在编写模块时,其中有一些代码,如测试代码,只希望在模块单独作为程序运行时被执行,可以放在 if __name__ == '__main__:'
中,建议格式如下
def main_or_test():
# 模块单独作为程序运行时,要执行的代码
pass
if __name__ == '__main__':
main_or_test()
例 如下编写一个模块 bar,放在当前 Python 执行文件同目录下
# bar.py
def baz():
print('baz is being called.')
baz()
使用 import 导入这个模块时,baz 函数被调用了
import bar
# baz is being called.
This is not exactly what we want. 得使用 if __name__ == '__main__:'
,就称心如意了
import bar
bar.baz()
# baz is being called.
进一步,使用 main
函数符合编程的传统
与函数文档类似,在开头使用成堆的三个连续双引号写一些内容,作为模块的文档,在调用时可以以 模块名.__doc__
查看内容
import profile
print(profile.__doc__)
# Class for profiling Python code.
若未在模块中编写 __all__
列表,那么 from 模块名 import *
(但也别这么导入)将导入所有 不以下划线开头的 变量、函数、类;
若在模块中编写了 __all__
列表,那么在 from 模块名 import * 时,会导入名字属于 __all__
列表元素的变量、函数、类。
导入模块后可以使用 模块名.__all__
查看该属性
import profile
print(profile.__all__)
# ['run', 'runctx', 'Profile']
将相关的模块放进一个目录,并在目录下创建一个 __init__.py 的文件。
例 在执行文件的同目录下创建名为 foo 的包,包含 bar 模块
import foo
foo.bar.baz()
# baz is being called.
文件夹中的 __init__.py 是 Python 包 的标识,应尽量保持简单。通常,除了必要的信息和 __all__ 放在 __init__.py,其他内容都放到模块文件中编写。
当使用 import
导入模块或包时,Python 将按以下优先级查找
import foo
foo.bar.baz()
# baz is being called.
# 接着,将 foo 包删除
import foo
foo.bar.baz()
# baz is being called.
可见,若程序未终止,那么在本次运行中 import foo
仍然可行,因为 foo 包已加载入内存中。
在 anaconda 默认环境(base)下,模块的搜索路径可由 sys.path
查看,按照其中的路径由前向后依此查找。
import sys
sys.path
# ['',
# '/Users/xxx/data',
# '/anaconda3/lib/python37.zip',
# '/anaconda3/lib/python3.7',
# '/anaconda3/lib/python3.7/lib-dynload',
# '/anaconda3/lib/python3.7/site-packages',
# '/anaconda3/lib/python3.7/site-packages/aeosa',
# '/anaconda3/lib/python3.7/site-packages/IPython/extensions',
# '/Users/xxx/.ipython']
''
表示 .py 执行文件所在的目录;'/anaconda3/lib/python3.7'
;'/anaconda3/lib/python3.7/site-packages'
;sys.path
之中 sys.path.append(new_path)
。