作为Python开发人员构建所需的最重要技能之一是能够运行Python脚本和代码。这将是了解代码是否按计划运行的唯一方法。这甚至是了解代码是否正常工作的唯一方法!
本文涉及如下四种运行python代码的方式:
- 操作系统的命令行工具
- Python的交互式模式
- IDE或者你最喜欢的文本编辑器
- 系统的文件管理系统,通过双击脚本图标执行
脚本 vs 模块
脚本通常指代包含逻辑顺序序列或批处理的文件。这通常是一个简单的程序,存储在纯文本文件中。脚本总是由某种解释器处理,解释器负责顺序执行每个命令。包含旨在由用户直接执行的Python代码的纯文本文件通常称为脚本,这是一个非正式术语,表示顶级程序文件(top-level program file)。
另一方面,如果一个包含python代码的文本文件被用于导入和被其它python文件使用,那么,我们可以称之为模块(module)。
因此,模块和脚本之间的主要区别在于,模块是要导入的,而脚本是直接执行的。
什么是python解释器?
Python是一门流行的编程语言,Python也是一个解释器的软件,该解释器是一个软件层,可以在程序和计算机硬件之间运行,以使代码运行。
根据Python的实现方式,解释器有以下几种:
- C语言写的程序, 比如 CPython, python语言的核心
- Java写的, 比如 Jython
- Python自己, 比如PyPy
- .NET写的, 例如 IronPython
交互式运行Python代码
这算是一种比较常见的方式了,直接打开命令提示符,敲入 python或者
python3
(依据python版本),然后回车,搞定。
比如在Linux中
$ python3
Python 3.6.7 (default, Oct 22 2018, 11:32:17)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
以交互方式工作时,键入的每个表达式和语句将立即被解释并执行
>>> print('Hello World!')
Hello World!
>>> 2 + 5
7
>>> print('Welcome to Real Python!')
Welcome to Real Python!
交互式会话的好处在于可以测试你的每一句代码,退出这种模式有如下两种方法:
- Python内置函数quit()或者exit().
- Window下, Ctrl+Z 和 Enter的组合键,Unix系统下 Ctrl+D搞定.
命令行模式下运行python脚本
在python交互式模式下,你可以随心所欲的写代码,执行代码,但是一旦你关闭会话了,那么,你所做的一切白费了,^_^!因此能,我们还是老老实实将代码写入文本文件中吧,通常这些文件的后缀为.py或者.pyw(windows下).
我们来新建一个python脚本,命名为hello.py,
1 #!/usr/bin/env python3
2
3 print('Hello World!')
使用python命令
打开命令行工具,敲入python这个单词,或者python3,后面接上脚本文件完整路径:
$ python3 hello.py
Hello World!
就是这么简单!如果出现问题了,可能在于python可执行文件没有加入环境变量中。
重定向输出
有些时候我们可能需要将脚本输出保存下来以备后续分析,可以这样做:
$ python3 hello.py > output.txt
此操作将脚本的输出重定向到output.txt,而不是标准系统输出(stdout)。该过程通常称为流重定向,可在Windows和类Unix系统上使用。
注意,如果 output.txt不存在,会自动新建,如果存在它里面的内容会被覆盖。
最后,如果要将连续执行的输出添加到output.txt的末尾,则必须使用两个尖括号(>>)而不是一个,如下所示:
$ python3 hello.py >> output.txt
这样输出会被追加到output.txt中
.
使用-m
选项运行模块
Python提供了一系列命令行选项,可以根据自己的需要使用它们。例如,如果要运行Python模块,可以使用命令python -m <module-name>。
-m选项使得python在sys.path中搜索模块名称,并将其内容作为__main__运行:
$ python3 -m hello # 注意没有.py
Hello World!
注意: module-name
必须是模块对象的名字, 不是字符串.
使用脚本名字
在最新版本的Windows上,只需在命令提示符处输入包含代码的文件名,即可运行Python脚本:
C:\devspace> hello.py
Hello World!
这种可能是因为Windows使用系统注册表和文件关联来确定用于运行特定文件的程序。
在类Unix系统中,我们同样可以做类似的操作,只需在脚本首行加上#!/usr/bin/env python.
对于Python,这是一个简单的注释,但对于操作系统,此行指示必须使用哪个程序来运行该文件。
这一行以#!字符组合开头(通常称为hash bang或shebang),后面接解释器的路径.
有两种方式为解释器指定python路径:
#!/usr/bin/python
: 绝对路径#!/usr/bin/env python
: 指定操作系统的环境变量,然后在这里面搜寻python的路径
最后,要执行类似这样的脚本,您需要为其分配执行权限,然后在命令行键入文件名。
$ # 赋予可执行权限
$ chmod +x hello.py
$ # 使用文件名运行脚本
$ ./hello.py
Hello World!
交互式运行python脚本
也可以从交互式会话中运行Python脚本和模块,这为我们提供各种可能性。
活用import
导入模块时,实际发生的是加载其内容以供以后访问和使用。关于这个过程的有趣之处在于import将代码作为最后一步运行。
当一个模块中只包含类,函数,变量和常数定义时,你可能并没有意识到代码真正的执行了,但是当模块中包含函数调用,方法或其他产生可见输出的语句时,你就会目睹代码的执行了。
这样我们就拥有了另一种运行python脚本的方式:
>>> import hello
Hello World!
务必记住,import这种操作一次会话只会执行一次,即使你更改了模块的内容他也不会再执行,因为这种操作是有很大花销的,所以请记住这点!
>>> import hello # 啥也不干
>>> import hello # 同样啥也不干
两次 import
操作啥也不干,但是Python知道 hello
已经成功导入.
这种方法有两个前提(满足一个即可):
- python文件必须位于当前工作目录.
- 文件必须位于 python模块搜素路径(Python Module Search Path (PMSP).
查询当前的PMSP执行如下代码:
>>> import sys
>>> for path in sys.path:
... print(path)
...
/usr/lib/python36.zip
/usr/lib/python3.6
/usr/lib/python3.6/lib-dynload
/usr/local/lib/python3.6/dist-packages
/usr/lib/python3/dist-packages
使用 importlib
和 imp
importlib是一个python标准库
, 提供函数 import_module()
.
import_module()
模拟 import
操作, 因此可以执行任何模块或脚本.来瞅个例子:
>>> import importlib
>>> importlib.import_module('hello')
Hello World!
<module 'hello' from '/home/username/hello.py'>
一旦第一次导入模块,将无法继续使用导入来运行它。在这种情况下,可以使用importlib.reload(),这将强制解释器再次重新导入模块,就像在以下代码中一样:
>>> import hello # First import
Hello World!
>>> import hello # Second import, which does nothing
>>> import importlib
>>> importlib.reload(hello)
Hello World!
<module 'hello' from '/home/username/hello.py'>
重要提示reload()
参数必须是模块对象,不是字符串:
>>> importlib.reload('hello')
Traceback (most recent call last):
...
TypeError: reload() argument must be a module
importlib.reload()老好用了,特别当你更改了模块内容,因为这并不需要你离开当前会话!
Python 2.x的话使用 imp.
imp.reload()
类似于 importlib.reload()
. 看例子:
>>> import hello # First import
Hello World!
>>> import hello # Second import, which does nothing
>>> import imp
>>> imp.reload(hello)
Hello World!
<module 'hello' from '/home/username/hello.py'>
使用 runpy.run_module()
和 runpy.run_path()
标准库中还有个好东西 runpy
. 这个模块中有个 run_module()
, 这是一个允许您在不先导入模块的情况下运行模块的功能.这可真是骚操作. 此函数返回已执行模块的全局字典。
>>> runpy.run_module(mod_name='hello')
Hello World!
{'__name__': 'hello',
...
'_': None}}
run_module()的第一个参数必须是模块名字的绝对路径,不含后缀.py
.
runpy
中run_path()需要加.py
:
>>> import runpy
>>> runpy.run_path(file_path='hello.py')
Hello World!
{'__name__': '<run_path>',
...
'_': None}}
exec()
到目前为止,已经看到了运行Python脚本最常用的方法。在本节中,将看到如何使用exec()来实现这一点,exec()是一个支持动态执行Python代码的内置函数。
>>> exec(open('hello.py').read())
'Hello World!'
打开 hello.py
, 读取内容, 喂给 exec()执行代码
,一气呵成!
使用execfile()
(Python 2.x 专属)
直接看代码:
>>> execfile('hello.py')
Hello World!
通过文件管理系统运行python代码
通过在文件管理器中双击其图标来运行脚本是运行Python脚本的另一种可能方式。此选项可能未在开发阶段广泛使用,但在发布生产代码时可能会使用此选项。
为了能够通过双击运行脚本,对操作系统有一些要求。
例如,Windows将扩展名.py和.pyw分别与程序python.exe和pythonw.exe相关联。我们可以通过双击它们来运行脚本。
结束
恭喜,技能升华!