Python 模块是扩展名为.py
的文件。这些可以用来实现一组属性(变量)、方法(函数)和类(类型)。只需使用后跟模块名称的import
语句,就可以在另一个 Python 程序中包含一个模块。要导入名为time
的模块,请在 Python 程序中包含import time
。您现在可以通过调用time.method_name()
来访问time
模块中的方法,或者通过调用time.attribute_name
来访问属性,有时称为变量。下面的代码清单是一个使用asctime()
方法和来自time
模块的timezone
属性的例子。timezone
属性包括世界协调时和当地时间之间的秒数。
代码清单 263
import time
print(time.asctime())
print(time.timezone)
输出:
代码清单 264
Tue Aug 25 14:28:03 2015
21600
无论何时import module_name
,该模块中的所有方法都将作为module_name.method_name()
可用。如果您选择在一个模块中使用单一方法,您可以使用from module_name import method_name
语法导入该方法。现在这个方法可以在你的程序中通过名字来访问。不再叫module_name.method_name()
,你现在可以简单的叫method_name()
。
代码清单 265
from time import asctime
print(asctime())
输出:
代码清单 266
Tue Aug 25 14:28:03 2015
使用模块属性和类可以做同样的事情。如果您希望从一个模块中导入多个项目,您可以为每个项目创建单独的from module_name import method_name
行。您也可以选择提供一个逗号分隔的列表,如:from module_name import method_name1, method_name2, method_nameN
。让我们从time
模块导入asctime()
和sleep()
方法。sleep()
方法暂停程序的执行一段指定的秒数。
代码清单 267
from time import asctime, sleep
print(asctime())
sleep(5)
print(asctime())
输出:
代码清单 268
Tue Aug 25 14:28:03 2015
Tue Aug 25 14:28:08 2015
从模块中导入单个方法或方法列表的主要好处之一是,您可以通过名称直接访问它,而不必在它前面加上模块名称。例如sleep(5)
对time.sleep(5)
。如果您希望能够访问模块中的所有内容,您可以使用星号来代替方法列表进行导入。不过,这不是我推荐的做法。这里值得一提,只是因为你会看到它不时被使用。最好避免这种方法的主要原因是,如果将所有内容都导入到程序中,就会冒覆盖现有函数或变量的风险。此外,当您使用星号导入多个方法时,您会发现很难确定到底是什么从哪里来的。
代码清单 269
from time import *
print(timezone)
print(asctime())
sleep(5)
print(asctime())
输出:
代码清单 270
21600
Tue Aug 25 14:28:03 2015
Tue Aug 25 14:28:08 2015
您可以使用内置的dir()
函数来发现任何一个模块中存在哪些属性、方法和类。
代码清单 271
>>> import time
>>> dir(time)
['_STRUCT_TM_ITEMS', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'altzone', 'asctime', 'clock', 'ctime', 'daylight', 'get_clock_info', 'gmtime', 'localtime', 'mktime', 'monotonic', 'perf_counter', 'process_time', 'sleep', 'strftime', 'strptime', 'struct_time', 'time', 'timezone', 'tzname', 'tzset']
请记住,您总是可以通过检查sys.path
来查看默认的模块搜索路径。每当您提供import module_name
语句时,Python 都会在列表的第一个路径中查找该模块。如果 Python 找不到它,那么将检查下一个路径,以此类推。这将持续下去,直到找到该模块,或者直到所有模块搜索路径完全用尽。模块搜索路径可能包括 zip 文件以及目录。Python 也会在 zip 文件中搜索匹配的模块。需要注意的是,默认的模块搜索路径会因您安装的 Python、Python 版本和操作系统而异。下面的代码清单是一个在苹果电脑上安装 Python 的例子。
代码清单 272
# show_module_path.py
import sys
for path in sys.path:
print(path)
输出:
代码清单 273
/Users/david
/Library/Frameworks/Python.framework/Versions/3.4/lib/python34.zip
/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4
/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/plat-darwin
/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/lib-dynload
/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages
当我第一次执行python3 show_module_path.py
时show_module_path.py
文件位于/Users/david
。注意/Users/david
列在模块搜索路径的第一位。其他目录由 Python 安装决定。
如果您想让 Python 在其他位置搜索模块,您需要操作模块搜索路径。有两种方法可以做到这一点。第一种方法是像修改任何其他列表一样修改sys.path
。例如,您可以使用字符串数据类型追加目录位置。
代码清单 274
import sys
sys.path.append('/Users/david/python')
for path in sys.path:
print(path)
输出:
代码清单 275
/Users/david
/Library/Frameworks/Python.framework/Versions/3.4/lib/python34.zip
/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4
/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/plat-darwin
/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/lib-dynload
/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages
/Users/david/python
您还可以操作PYTHONPATH
环境变量。该变量的作用方式与PATH
环境变量非常相似。在 Mac 和 Linux 系统上,PYTHONPATH
可以用冒号分隔的目录列表填充。在 Windows 系统上,PYTHONPATH
环境变量需要使用分号来分隔目录列表。在PYTHONPATH
中列出的目录被插入脚本所在的目录之后,默认模块搜索路径之前。
在下面的例子中,/Users/david
是show_module_path.py
Python 程序所在的目录。/Users/david/python
和/usr/local/python/modules
路径包含在PYTHONPATH
中。export
命令使从外壳启动的程序可以使用PYTHONPATH
。
代码清单 276
[david@mac ~]$ export PYTHONPATH=/Users/david/python:/usr/local/python/modules
[david@mac ~]$ pwd
/Users/david
[david@mac ~]$ python3 show_module_path.py
/Users/david
/Users/david/python
/usr/local/python/modules
/Library/Frameworks/Python.framework/Versions/3.4/lib/python34.zip
/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4
/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/plat-darwin
/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/lib-dynload
/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages
[david@mac ~]$
如果在搜索路径中找不到模块,将会出现ImportError
异常。
代码清单 277
import say_hello
输出:
代码清单 278
Traceback (most recent call last):
File "test_say_hello.py", line 1, in <module>
import say_hello
ImportError: No module named 'say_hello'
正如我们在前面的例子中所做的,我们一直在使用 Python 附带的时间模块。事实上,Python 提供了一个很大的模块库供您利用。我强烈建议您在考虑编写自己的代码之前,花点时间真正了解一下 Python 标准库能提供什么。例如,如果您希望读写 CSV(逗号分隔值)文件,不要浪费时间从头开始创建已经存在的东西。只需使用 Python 预先存在的csv
模块。您是否希望在程序中启用登录?嗯,有一个logging
模块可以帮助你做到这一点。您想向 web 服务发出 HTTP 请求,然后解析 JSON 响应吗?尝试使用urllib.request
和json
模块。要了解这些模块和更多内容,请查看位于https://docs.python.org/3/library/的 Python 标准库的列表。
现在,让我们使用sys
模块中的exit()
方法,如果检测到错误,干净利落地终止您的程序。在下面的例子中,文件test.txt
被打开。如果程序在打开文件时遇到错误,将执行except:
后面的代码块。如果阅读test.txt
是剩余代码正常运行的必要条件,则无需继续。exit()
方法可以接受退出代码作为参数。如果未提供退出代码,将使用0
。按照惯例,当错误导致程序退出时,需要非零退出代码。
代码清单 279
import sys
file_name = 'test.txt'
try:
with open(file_name) as test_file:
for line in test_file:
print(line)
except:
print('Could not open {}.'.format(file_name))
sys.exit(1)
正如 Python 有自己的可重用代码库一样,您也可以。创建自己的模块非常简单。请记住,在最简单的形式中,模块是扩展名为.py
的文件。只需用你的代码创建一个 Python 文件并从另一个 Python 程序中import
它。
以下代码清单是say_hello.py
的内容。
代码清单 280
def say_hello():
print('Hello!')
注意如何导入和使用say_hello
模块。要调用say_hello
模块中的say_hello()
方法,请使用say_hello.say_hello()
。
代码清单 281
import say_hello
say_hello.say_hello()
输出:
代码清单 282
Hello!
下面的例子是另一个叫做say_hello2
的简单模块。以下代码是say_hello2.py
的正文。
代码清单 283
def say_hello():
print('Hello!')
print('Hello from say_hello2.py!')
让我们看看当你导入say_hello2
模块时会发生什么。
代码清单 284
import say_hello2
say_hello2.say_hello()
输出:
代码清单 285
Hello from say_hello2.py!
Hello!
发生了什么?当say_hello2
被导入时,它的内容被执行。首先,定义say_hello()
功能。从那里执行print
功能。通过这种方式,Python 使您能够创建在执行时以一种方式运行的程序,以及在导入时以另一种方式运行的程序。如果您希望能够重用现有 Python 程序中的函数,但不想执行主程序,您可以考虑这一点。
每当 Python 文件作为程序执行时,特殊变量__name__
将被设置为__main__
。请注意,这些特殊变量的名称两边各有两个下划线字符。在导入的情况下,__name__
变量将不被填充。最终,您可以使用它来控制 Python 程序的行为。以下代码示例是say_hello3.py
文件。
代码清单 286
def say_hello():
print('Hello!')
def main():
print('Hello from say_hello3.py!')
say_hello()
if __name__ == '__main__':
main()
无论何时作为程序执行,都会执行if __name__ == '__main__'
之后的代码块。在下面的例子中,它简单地称为main()
。这是一种非常常见的模式,您将在许多 Python 应用程序中看到这一点。当say_hello3.py
作为模块导入时,除非从导入程序中明确调用,否则不会执行任何操作。
代码清单 287
[david@mac ~]$ python3 say_hello3.py
Hello from say_hello3.py!
Hello!
[david@mac ~]$
Python 模块是扩展名为. py 的文件,能够实现一组变量、函数和类。
使用import module_name
语法导入模块。
默认模块搜索路径将由您的 Python 安装决定。
要操作模块搜索路径,修改sys.path
或设置PYTHONPATH
环境变量。
Python 标准库是一个相当大的代码集合,可以在您的 Python 程序中重用。
使用dir()
内置功能,找出模块中存在的确切内容。
您可以通过编写自己的模块来建立自己的个人库。
通过检查___name___
的值,您可以根据 Python 程序是交互运行还是导入来影响其行为。
if __name__ == '__main__':
语法是一个常见的 Python 习语。
更新我们在第 1 章讨论的“猪语”程序,使其可以作为模块导入或直接运行。当作为一个程序运行时,它应该提示输入,并显示一只猪“说”用户提供了什么。将用户提供的输入放入语音气泡中。这个语音气泡可以扩展或收缩,以适应用户提供的输入。
下面的代码清单显示了交互运行时的示例输出。
代码清单 288
______________________
< Pet me and I will oink >
----------------------
/
^..^ /
~( ( oo )
,, ,,
从这里,创建一个名为pig_talk.py
的新程序,导入pig_say
模块。尝试使用pig_say()
模块中的功能向屏幕显示各种信息。
下面的代码清单显示了作为模块使用时的示例输出。
代码清单 289
________
< Feed me. >
--------
/
^..^ /
~( ( oo )
,, ,,
____________
< Oink. Oink. >
------------
/
^..^ /
~( ( oo )
,, ,,
以下代码是pig_say.py
的内容。
代码清单 290
def pig_say(text):
"""Generate a picture of a pig saying something"""
text_length = len(text)
print(' {}'.format('_' * text_length))
print(' < {} >'.format(text))
print(' {}'.format('-' * text_length))
print(' /')
print(' ^..^ /')
print('~( ( oo )')
print(' ,, ,,')
def main():
text = input('What would you like the pig to say? ')
pig_say(text)
if __name__ == '__main__':
main()
以下代码是pig_talk.py
的内容。
代码清单 291
import pig_say
def main():
pig_say.pig_say('Feed me.')
pig_say.pig_say('Oink. Oink.')
if __name__ == '__main__':
main()
__main__
文件:https://docs.python.org/3/library/main.html
Python 中的习语和反习语:https://docs.python.org/3.1/howto/doanddont.html
新手 Linux:http://www.linuxtrainingacademy.com/linux。
PYTHONPATH
文档:https://docs . python . org/3/using/cmdline . html # env var-PYTHONPATH
Python 标准库:https://docs.python.org/3/library/
sys
模块:https://docs.python.org/3/library/sys.html
sys.path
文件:https://docs.python.org/3/library/sys.html#sys.path
virtualenv
文件:https://pypi . python . org/pypi/virtualenv