《Python语言及其应用》读书笔记(4)之第5章Python盒子:模块、包和程序(关键词:模块/包/程序)

第 5 章 Python盒子:模块、包和程序

5.1 独立的程序

5.2 命令行参数

5.3 模块和import语句

一个模块仅仅是Python代码的一个文件。

5.3.1 导入模块

一个例子:

>>> import random
>>> def get_description():
...     possibilities = ['rain', 'snow', 'sleet', 'fog', 'sun', 'who knows']
...     return random.choice(possibilities)
...
>>> get_description()
'who knows'
>>> get_description()
'rain'

5.3.2 使用别名导入模块

5.3.3 导入模块的一部分

5.3.4 模块搜索路径

Python 会在什么地方寻找文件来导入模块?使用命名为 path 变量的存储在标准 sys 模块下的一系列目录名和 ZIP 压缩文件。你可以读取和修改这个列表。

>>> import sys
>>> for element in sys.path:
...     print(element)
... 

/usr/lib/python35.zip
/usr/lib/python3.5
/usr/lib/python3.5/plat-x86_64-linux-gnu
/usr/lib/python3.5/lib-dynload
/home/henry/.local/lib/python3.5/site-packages
/usr/local/lib/python3.5/dist-packages
/usr/lib/python3/dist-packages
>>> sys.path
['', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-x86_64-linux-gnu', '/usr/lib/python3.5/lib-dynload', '/home/henry/.local/lib/python3.5/site-packages', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python3/dist-packages']

最开始的空白输出行是空字符串 ”,代表当前目录。如果空字符串是在sys.path 的开始位置, Python 会先搜索当前目录: import report 会寻找文件 report.py。
第一个匹配到的模块会先被使用, 这也就意味着如果你在标准库之前的搜索路径上定义一个模块 random,就不会导入标准库中的random 模块。

5.4 包

我们已使用过单行代码、多行函数、独立程序以及同一目录下的多个模块。为了使 Python应用更具可扩展性,你可以把多个模块组织成文件层次,称之为包。
详细见书上。

5.5 Python标准库

5.5.1 使用setdefault()和defaultdict()处理缺失的键

函数 setdefault() 类似于 get(), 但当键不存在时它会在字典中添加一项:

>>> periodic_table = {'Hydrogen': 1, 'Helium': 2}
>>> print(periodic_table)
{'Helium': 2, 'Hydrogen': 1}

如果键不在字典中,新的默认值会被添加进去:

>>> carbon = periodic_table.setdefault('Carbon', 12)
>>> carbon
12
>>> periodic_table
{'Helium': 2, 'Carbon': 12, 'Hydrogen': 1}

如果试图把一个不同的默认值赋给已经存在的键,不会改变原来的值,仍将返回初始值:

>>> helium = periodic_table.setdefault('Helium', 947)
>>> helium
2
>>> periodic_table
{'Helium': 2, 'Carbon': 12, 'Hydrogen': 1}

defaultdict() 也有同样的用法,但是在创建字典时,对每个新的键都会指定默认值。它的参数是一个函数。在本例中,把函数 int 作为参数传入,会按照 int() 调用,返回整数 0:

>>> from collections import defaultdict
>>> periodic_table = defaultdict(int)

现在,任何缺失的值将被赋为整数 0:

>>> periodic_table['Hydrogen'] = 1
>>> periodic_table['Lead']
0
>>> periodic_table
defaultdict(<class 'int'>, {'Lead': 0, 'Hydrogen': 1})

函数 defaultdict() 的参数是一个函数,它返回赋给缺失键的值。
在下面的例子中, no_idea() 在需要时会被执行,返回一个值:

>>> from collections import defaultdict
>>>
>>> def no_idea():Python盒子:模块、包和程序 | 101
...     return 'Huh?'
...
>>> bestiary = defaultdict(no_idea)
>>> bestiary['A'] = 'Abominable Snowman'
>>> bestiary['B'] = 'Basilisk'
>>> bestiary['A']
'Abominable Snowman'
>>> bestiary['B']
'Basilisk'
>>> bestiary['C']
'Huh?'

同样,可以使用函数 int()、 list() 或者 dict() 返回默认空的值: int()返回 0, list()返回空列表([]), dict() 返回空字典({})。如果你删掉该函数参数,新键的初始值会被设置为 None。

5.5.2 使用Counter()计数

>>> from collections import Counter
>>> breakfast = ['spam', 'spam', 'eggs']
>>> breakfast_counter = Counter(breakfast)
>>> breakfast_counter
Counter({'spam': 2, 'eggs': 1})

5.5.3 使用有序字典OrderedDict()按键排序

有序字典 OrderedDict() 记忆字典键添加的顺序,然后从一个迭代器按照相同的顺序返回。

5.5.4 双端队列:栈+队列

deque 是一种双端队列,同时具有栈和队列的特征。它可以从序列的任何一端添加和删除项。现在,我们从一个词的两端扫向中间,判断是否为回文。函数 popleft() 去掉最左边的项并返回该项, pop() 去掉最右边的项并返回该项。从两边一直向中间扫描,只要两端的字符匹配,一直弹出直到到达中间:

>>> def palindrome(word):
...     from collections import deque
...     dq = deque(word)
...     while len(dq) > 1:
...         if dq.popleft() != dq.pop():
...             return False
...     return True
...
...
>>> palindrome('a')
True
>>> palindrome('racecar')104 | 第 5 章
True
>>> palindrome('')
True
>>> palindrome('radar')
True
>>> palindrome('halibut')
False

如果想要写一个快速的判断回文的程序,只需要把字符串反转和原字符串进行比较。 Python 没有对字符串进行反转的函数reverse(),但还是可以利用反向切片的方式进行反转,如下所示:

>>> def another_palindrome(word):
... return word == word[::-1]
...
>>> another_palindrome('radar')
True
>>> another_palindrome('halibut')
False

5.5.5 使用itertools迭代代码结构

itertools(https://docs.python.org/3/library/itertools.html)包含特殊用途的迭代器函数。在for … in 循环中调用迭代函数,每次会返回一项,并记住当前调用的状态。
即使 chain() 的参数只是单个迭代对象,它也会使用参数进行迭代:

>>> import itertools
>>> for item in  itertools.chain([1, 2], ['a', 'b']):
...     print(item)
... 
1
2
a
b

5.5.6 使用pprint()友好输出

我们见到的所有示例都用 print()(或者在交互式解释器中用变量名)打印输出。有时输
出结果的可读性较差。我们需要一个友好输出函数,比如 pprint():

>>> from pprint import pprint
>>> quotes = OrderedDict([
...     ('Moe', 'A wise guy, huh?'),
...     ('Larry', 'Ow!'),
...     ('Curly', 'Nyuk nyuk!'),
...     ])
>>>

普通的 print() 直接列出所有结果:

>>> print(quotes)
OrderedDict([('Moe', 'A wise guy, huh?'), ('Larry', 'Ow!'), ('Curly', 'Nyuk nyuk!')])

但是, pprint() 尽量排列输出元素从而增加可读性:

>>> pprint(quotes)
{'Moe': 'A wise guy, huh?',
'Larry': 'Ow!',
'Curly': 'Nyuk nyuk!'}

参考文献:
1. 《Python语言及其应用》。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值