目录 | 上一节 (3.4 模块) | 下一节 (3.6 设计讨论)

3.5 主模块

本节介绍主程序(主模块)的概念

主函数

在许多编程语言中,存在一个主函数或者主方法的概念。

// c / c++
int main(int argc, char *argv[]) {
...
}
// java
class myprog {
public static void main(String args[]) {
...
}
}

这是启动应用程序时执行的第一个函数。

Python 主模块

Python 没有主函数(main function)或主方法(main method)。相反,Python 有一个主模块(main

module)。主模块是第一个运行的源文件。

bash % python3 prog.py
...

在应用程序启动时,提供给解释器的任何文件都将成为主模块。名字并不重要。

__main__ 检查

对于作为主脚本运行的模块,使用此约定(译注:__main__ 检查)是标准做法。

# prog.py
...
if __name__ == '__main__':
# Running as the main program ...
statements
...

if 里面的语句称为主程序( main program)。

主程序与库导入

任何 Python 文件都可以作为主程序运行,或者作为一个库(译注:library,在 Python 中 library 既可以指模块 module,也可以指包 package),导入后运行。

bash % python3 prog.py # Running as main
import prog   # Running as library import

在这两种情况下,__name__ 都是模块的名称(译注:prog)。然而,如果作为主程序运行,__name__ 只能被设置为 __main__

通常,我们不希望主程序中的语句在库导入的时候执行。所以,通常在代码中包含一个 if- 检查,判断当前文件是否是主程序(译注:如果当前程序不是主程序,则 if __name__ == '__main__': 里面的语句不执行)。

if __name__ == '__main__':
# Does not execute if loaded with import ...

程序模板

这里有一个用于编写 Python 程序的通用模板:

# prog.py
# Import statements (libraries)
import modules # Functions
def spam():
... def blah():
... # Main function
def main():
... if __name__ == '__main__':
main()

命令行工具

Python 通常在命令行工具中使用:

bash % python3 report.py portfolio.csv prices.csv

这意味着脚本在 shell 或者 终端(terminal)执行。通常用于自动化,后台任务等。

命令行参数

命令行参数是一个文本字符串列表。

bash % python3 report.py portfolio.csv prices.csv

该文本字符串列表可以在 sys.argv 中找到。

# In the previous bash command
sys.argv # ['report.py, 'portfolio.csv', 'prices.csv']

这里有一个处理参数的简单示例:

import sys

if len(sys.argv) != 3:
raise SystemExit(f'Usage: {sys.argv[0]} ' 'portfile pricefile')
portfile = sys.argv[1]
pricefile = sys.argv[2]
...

标准 I/O

标准输入/输出(或者stdio)是和普通文件使用相同工作方式的文件。

sys.stdout
sys.stderr
sys.stdin

默认情况下,打印定向到 sys.stdout 文件。输入是从 sys.stdin 文件读取。回溯和错误定向到 sys.stderr 文件。

请注意,标准输入/输出(stdio)可以连接到终端(terminals),文件(files),管道(pipes)等。

bash % python3 prog.py > results.txt
# or
bash % cmd1 | python3 prog.py | cmd2

环境变量

环境变量在 shell 中设置。

bash % setenv NAME dave
bash % setenv RSH ssh
bash % python3 prog.py

os.environ 是包含这些值的字典。

import os

name = os.environ['NAME'] # 'dave'

更改会反映在程序随后启动的任何子进程中。

程序退出

通过异常处理程序退出。

raise SystemExit
raise SystemExit(exitcode)
raise SystemExit('Informative message')

其它方式。

import sys
sys.exit(exitcode)

非零(non-zero )退出码表示错误。

#!

在 Unix 系统中,#! 行指定某个路径下的 Python 解释器来执行该脚本(译注:#! 称为 Shebang 或者 hashbang,因为 # 号通常称为 hash 或者 sharp,而 ! 号则常常称为 bang)。将以下内容添加到脚本文件的第一行。

#!/usr/bin/env python3
# prog.py
...

(译注:#!/usr/bin/env python3 的意思——到 Unix 系统 env 所包含的全部环境变量中寻找 Python3 解释器,并使用 Python3 解释器执行该脚本)

执行脚本需要脚本具有可执行权限。

bash % chmod +x prog.py
# Then you can execute
bash % prog.py
... output ...

注意:Windows 系统上的 Python 启动器也会寻找 #! 行以指示语言版本。

脚本模板

最后,这里有一个通用代码模板,用于将 Python 程序作为命令行脚本运行:

#!/usr/bin/env python3
# prog.py # Import statements (libraries)
import modules # Functions
def spam():
... def blah():
... # Main function
def main(argv):
# Parse command line args, environment, etc.
... if __name__ == '__main__':
import sys
main(sys.argv)

练习

练习 3.15:main() 函数

report.py 文件中添加一个 main() 函数,该函数接受命令行选项列表,并生成与以前相同的输出。修改后,应该能够像下面这样交互地运行它:

>>> import report
>>> report.main(['report.py', 'Data/portfolio.csv', 'Data/prices.csv'])
Name Shares Price Change
---------- ---------- ---------- ----------
AA 100 9.22 -22.98
IBM 50 106.28 15.18
CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34
GE 95 13.48 -26.89
MSFT 50 20.89 -44.21
IBM 100 106.28 35.84
>>>

请修改 pcost.py 文件,添加一个类似的 main() 函数。

>>> import pcost
>>> pcost.main(['pcost.py', 'Data/portfolio.csv'])
Total cost: 44671.15
>>>

练习 3.16:编写脚本

请修改 report.pypcost.py 程序,以便它们在命令行上可以作为脚本执行:

bash $ python3 report.py Data/portfolio.csv Data/prices.csv
Name Shares Price Change
---------- ---------- ---------- ----------
AA 100 9.22 -22.98
IBM 50 106.28 15.18
CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34
GE 95 13.48 -26.89
MSFT 50 20.89 -44.21
IBM 100 106.28 35.84 bash $ python3 pcost.py Data/portfolio.csv
Total cost: 44671.15

目录 | 上一节 (3.4 模块) | 下一节 (3.6 设计讨论)

注:完整翻译见 https://github.com/codists/practical-python-zh

翻译:《实用的Python编程》03_05_Main_module的更多相关文章

  1. 翻译:《实用的Python编程》InstructorNotes

    实用的 Python 编程--讲师说明 作者:戴维·比兹利(David Beazley) 概述 对于如何使用我的课程"实用的 Python 编程"进行教学的问题,本文档提供一些通用 ...

  2. 翻译:《实用的Python编程》README

    欢迎光临 大约 25 年前,当我第一次学习 Python 时,发现 Python 竟然可以被高效地应用到各种混乱的工作项目上,我立即被震惊了.15 年前,我自己也将这种乐趣教授给别人.教学的结果就是本 ...

  3. 翻译:《实用的Python编程》05_02_Classes_encapsulation

    目录 | 上一节 (5.1 再谈字典) | 下一节 (6 生成器) 5.2 类和封装 创建类时,通常会尝试将类的内部细节进行封装.本节介绍 Python 编程中有关封装的习惯用法(包括私有变量和私有属 ...

  4. 翻译:《实用的Python编程》04_02_Inheritance

    目录 | 上一节 (4.1 类) | 下一节 (4.3 特殊方法) 4.2 继承 继承(inheritance)是编写可扩展程序程序的常用手段.本节对继承的思想(idea)进行探讨. 简介 继承用于特 ...

  5. 翻译:《实用的Python编程》01_02_Hello_world

    目录 | 上一节 (1.1 Python) | 下一节 (1.3 数字) 1.2 第一个程序 本节讨论有关如何创建一个程序.运行解释器和调试的基础知识. 运行 Python Python 程序始终在解 ...

  6. 翻译:《实用的Python编程》03_03_Error_checking

    目录 | 上一节 (3.2 深入函数) | 下一节 (3.4 模块) 3.3 错误检查 虽然前面已经介绍了异常,但本节补充一些有关错误检查和异常处理的其它细节. 程序是如何运行失败的 Python 不 ...

  7. 翻译:《实用的Python编程》03_04_Modules

    目录 | 上一节 (3.3 错误检查) | 下一节 (3.5 主模块) 3.4 模块 本节介绍模块的概念以及如何使用跨多个文件的函数. 模块和导入 任何一个 Python 源文件都是一个模块. # f ...

  8. 翻译:《实用的Python编程》04_01_Class

    目录 | 上一节 (3.6 设计讨论) | 下一节 (4.2 继承) 4.1 类 本节介绍 class 语句以及创建新对象的方式. 面向对象编程(OOP) 面向对象编程是一种将代码组织成对象集合的编程 ...

  9. 翻译:《实用的Python编程》05_00_Overview

    目录 | 上一节 (4 类和对象) | 下一节 (6 生成器) 5. Python 对象的内部工作原理 本节介绍 Python 对象的内部工作原理.来自其它语言的程序员通常会发现 Python 的类概 ...

随机推荐

  1. 【noi 2.6_7627】鸡蛋的硬度(DP)

    题意:其中n表示楼的高度,m表示你现在拥有的鸡蛋个数. 解法:f[i][j]表示 i 层楼有 j 个鸡蛋时,至少要扔多少次.3重循环,k为测试的楼层,分这时扔下去的鸡蛋碎和不碎的情况.要注意初始化. ...

  2. fzu2178礼物分配 (状压+二分)

    Problem Description 在双胞胎兄弟Eric与R.W的生日会上,他们共收到了N个礼物,生日过后他们决定分配这N个礼物(numv+numw=N).对于每个礼物他们俩有着各自心中的价值vi ...

  3. log查看工具log2console

    log查看工具log2console介绍:https://www.cnblogs.com/TianFang/archive/2013/03/27/2985296.html Log2Console日志监 ...

  4. k8s二进制部署 - node节点安装

    创建kubelet配置 • set-cluster # 创建需要连接的集群信息,可以创建多个k8s集群信息 [root@hdss7-21 ~]# kubectl config set-cluster ...

  5. Rails框架学习

    Don't Repeat Yourself! Convention Over Configuration. REST. Rails框架总览. Rails框架基本使用. Rails框架数据交互. Rai ...

  6. API 授权 All In One

    API 授权 All In One 身份验证 授权类型 身份验证类型 继承认证 没有认证 API密钥 不记名令牌 基本认证 摘要授权 OAuth 1.0 OAuth 2.0 授权码 隐含的 密码凭证 ...

  7. holy shit CSDN

    holy shit CSDN 垃圾 CSDN 到处都是垃圾文章, 无人子弟 到处都是垃圾广告,看的恶心 毫无底线,窃取别人的知识成果,毫无版权意识 垃圾爬虫,垃圾小号 ...等等 Google Sea ...

  8. ESLint & jsx-quotes & quotes

    ESLint & jsx-quotes & quotes bug { "jsx-quotes": [ "error", "prefer ...

  9. macOS 屏幕共享, 远程协助

    macOS 屏幕共享, 远程协助 Screen Sharing App 隐藏 app bug command + space 搜索 https://macflow.net/p/397.html Tea ...

  10. DeFi里的灰度?每月获得高收益?BGV代币初探

    2020年已经接近了尾声,但是DeFi市场的热闹场面并没有停止,或者说,一直在延续.资本市场不断将大批的资金投入到DeFi市场中,以求在这波热潮中赚得一波又一波红利. 美国时间12月21日,Bacca ...