Skip to content

dawin2015/Python-Cookbook

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Python-Cookbook

供平时学习查询使用,中文为简单提示,代码详见源码对应的题号,如1.3对应1_3.py

第一章 数据结构和算法

1.1 将序列分解为单独的变量
任何序列(可迭代的对象)都可以通过一个简单的赋值操作来分解为单独的变量,唯一的要求是变量的总数和结构要和序列相吻合。
1.2 从任意长度的可迭代对象中分解元素
"*表达式"
1.3 保存最后N个元素
from collections import deque
1.4 找出最大或最小的N个元素
import heapd
返回nums中前三个最大值heap.nlargest(3, nums)
返回nums中前三个最小值heap.nsmallest(3, nums)
生成小端堆heap.heapify(nums)
讲第一个元素(最小的)弹出heap.heappop()
1.5 实现优先级队列 实现一个队列,能够以给定的优先级来对元素排序,且每次pop操作时都会返回优先级最高的那个元素
import heapq
1.6 在字典中将键映射到多个值上
from collections import defaultdict
1.7 让字典保持有序
创建一个字典,同时当对字典做迭代或序列化操作时,也能控制其中元素的顺序;当构建一个映射结构以便稍后对其做序列化或编码成另一个格式时,OrderedDict(双向链表)显得特别有用,请注意OrderedDict的大小是普通字典的两倍
from collections import OrderedDict
1.8 与字典有关的计算问题
利用zip()将字典的键和值反转,如果碰巧多个条目拥有相同的value值时,key将用来作为判定结果的依据
1.9 在两个字典中寻找相同点
通过keys()或items()方法执行常见的集合操作即可
如: a.keys() & b.keys()
a.keys() - b.keys()
a.items() & b.items()
1.10 从序列中移除重复项且保持元素间顺序不变
def dedupe()
1.11 对切片命名
内置的slice()函数会创建一个切片对象,可以用在任何允许进行切片操作的地方;如果有一个slice对象的实例s,可以分别通过s.start, s.stop, s.step属性得到关于该对象的信息;可以通过使用indices(size)方法将切片映射到特定大小的序列上,返回一个(start, stop, step)元祖,所有的值都已经恰当地限制在边界以内,避免出现IndexError异常。
1.12 找出序列中出现次数最多的元素
from collections import Counter
1.13 通过公共键对字典列表排序
from operator import itemgetter
1.14 对不原生支持比较操作的对象排序
from operator import attrgetter
1.15 根据字段将记录分组
from itertools import groupby
from collections import defaultdict
1.16 筛选序列中的元素
filter
如果想把对一个序列的筛选结果施加到另一个相关的序列上时,使用itertools.compress(),输出时会给出所有在相应的布尔选择器中为True的可迭代对象元素。
from itertools import compress 1.17 从字典中提取子集
利用字典推导式:p = {key:value for key, value in prices.items() if value > 200}
1.18 将名称映射到序列的元素中
from collections import namedtuple
1.19 同时对数据做转换和换算
在函数参数中使用生成器表达式。
1.20 将多个映射合并为单个映射
from collections import ChainMap

第二章 字符串和文本

2.1 针对任意多的分隔符拆分字符串
import re
2.2 在字符串的开头或结尾处做文本匹配
用来检查字符串的开头或结尾,使用str.startswith()和str.endswith()方法即可。
2.3 利用Shell通配符做字符串匹配
fnmatch模块提供了两个函数——fnmatch()和fnmatchcase(),可用来执行这样的匹配。fnmatch所完成的匹配操作有点介乎于简单的字符串方法和全功能的正则表达式之间,在处理数据时提供一种简单的机制以允许使用通配符。
from fnmatch import fnmatch, fnmatchcase
2.4 文本模式的匹配和查找
re.match()方法总是尝试在字符串的开头找到匹配项;re.findall()方法针对整个文本搜索出所有的匹配项;当定义正则表达时,将部分模式用括号包起来的方式引入捕获组,从而每个组的内容都可以单独提取出来;re.finditer()方法以迭代的方式找出匹配项
2.5 查找和替换文本
import re
使用re.sub()方法,第一个参数的要匹配的模式,第二个参数的要替换上的模式
2.6 以不区分大小写的方式对文本做查找和替换
import re
若待替换的文本与匹配的文本大小写不吻合,需要用到一个支撑函数
2.7 定义实现最短匹配的正则表达式
*操作符在正则表达式中的采用的是贪心策咯,所以匹配过程是基于找出最长的可能匹配来进行的,要解决这个问题,只要在模式中的*操作符后加上?修饰符即可。
2.8 编写多行模式的正则表达式
re.complie()函数可接受一个有用的标记——re.DOTALL,使得正则表达式中的句点(.)可以匹配所有的字符,也包括换行符。
2.9 将Unicode文本统一表示为规范形式
import unicodedata
2.10 用正则表达式处理Unicode字符
Unicode和正则表达式混在一起使用绝对是个能让人头痛欲裂的办法,建议考虑安装第三方的正则表达式库regex
2.11 从字符串中去掉不需要的字符
strip()方法可用来从字符串的开始和结尾处去掉字符;lstrip()和rstrip()可分别从左或从右侧开始执行去除字符的操作;默认情况下这些方法去除的是空格符,但也可以指定其他的字符。
2.12 文本过滤和清理 复杂的文本过滤和清理可以考虑使用str.translate()方法
2.13 对齐文本字符串
基本的字符串对齐要求,可以使用字符串的ljust()、rjust()、center()方法;建议使用format()方法,该方法更通用,可作用于任意类型的对象。
2.14 字符串连接及合并
想要合并的字符串在一个序列或可迭代对象中,最快的方法是使用join()方法;如果只是想连接一些字符串,一般使用+操作符就足够了,但不适用在大量的字符串连接;打印的时候可以用
printf(a, b, c, sep=':')
避免使用
printf(a + ':' + b + ':' + c )
2.15 给字符串中的变量名做插值处理
通过format()方法近似模拟:
s = '{name} has {n} message.'
s.format(name='Guido', n=37)
或format_map()和vars()联合使用。
2.16 以固定的列数重新格式化文本
可以使用textwarp模块来重新格式化文本的输出;可以通过os.get_terminal_size()来获取终端的大小。
2.17 在文本中处理HTML和XML实体
如果要生成文本,使用html.escape()函数来完成替换这样的特殊字符相对来说是比较容易的;如果实际上是在处理HTML或XML,首先应该尝试使用一个合适的HTML或XML解释器。
2.18 文本分词
(非常复杂,涉及正则表达式,而且比较容易出错)关注下一节的PLY。
2.19 编写一个简单的递归下降解析器
(详见教材,比较复杂)
2.20 在字节串上执行文本操作
如果要同文本打交道,在程序中使用普通的文本字符串就好,不要用字符串。

第三章 数字、日期和时间

TODO

第四章 迭代器和生成器

4.1 手动访问迭代器中的元素
要手动访问可迭代对象中的元素,可以使用next()函数。
4.2 委托迭代
一般来说,要做的就是定义一个__iter__()方法,将迭代请求委托到对象内部持有的容器上即可,实际上由该对象内部实现的__next__()方法完成实际的迭代。
4.3 用生成器创建新的迭代模式
函数中只要出现了yield语音就会将其转换成一个生成器。
4.4 实现迭代协议
要在对象上实现可迭代功能,最简单的方式就是使用生成器函数,如下实现深度优先遍历。
....
def iter(self):
  return iter(self._childer)

def depth_first(self):
  yield self
  for c in self:
    yield from c.depth_first()
....

4.5 反向迭代
可以使用内建的reversed()函数实现反向迭代,但注意将可迭代对象转换成列表可能会消耗大量内存;在对象中实现__reverse__()方法,就可以在自定义的类中上实现反向迭代。
4.6 定义带有额外状态的生成器函数
如果想让生成器将状态暴露给用户,可以将其实现为一个类,然后把生成器函数的代码放到__iter__()方法中即可。
4.7 对迭代器做切片操作
使用itertools.islice()函数,如:
for x in itertools.islice(c, 10, 20)
重点强调的是islice()会消耗掉所提供的迭代器中的数据。由于迭代器中的元素只能访问一次,没法倒回去,因此如果往后还需要倒回去访问前面的数据,需要先将数据转到列表中去。
4.8 跳过可迭代对象中的前一部分元素
第一种办法是使用itertools。dropwhile()函数,要提供一个函数和一个可迭代对象,该函数返回的迭代器会丢弃掉序列中的前面几个元素,只要它们在所提供的函数中返回True即可:
for line in dropwhile(lambda line: line.startwith('#'), f):
第二种办法是,如果知道要跳过多少个函数,可以使用itertools.islice()函数:
for x in islice(item, 3, None):
最后一个参数None表示想要前3个元素之外的所有元素,即表示切片[3:]
4.9 迭代所有可能的组合或排列
排列使用itertools.permutations()
组合使用itertools.combinations()
4.10 以索引-值对的形式迭代序列
当在元组序列上应用enumerate()时,如果元组本身也被分解展开的话就会出错,要正确处理其对应关系。
4.11 同时迭代多个序列
可以使用zip()函数同时迭代多个序列,整个迭代的长度和其中最短的输入序列长度相同;如果这种行为不是所需要的,可以使用itertools.zip_longest()来代替。
4.12 在不同的容器中进行迭代
需要对许多对象执行相同的操作,但是这些对象包含在不同的容器内,要避免嵌套循环处理,保持代码的可读性,itertools.chain()方法可以用来简化这个任务,对多个容器进行迭代。
4.13 创建处理数据的管道
import os
4.14 扁平化处理嵌套型的序列
from collections import Iterable
4.15 合并多个有序序列,再对整个有序序列进行迭代
import heapq
重点强调的是,heapq.merge()要求所有的输入序列都是有序的。特别是,它不会首先将所有的数据读取到堆中,或者预先做任何排序的操作。它也不会对输入做任何验证,以检查它们是否满足有序的要求。相反,它只是简单的检查每个输入序列中的第一个元素,将最小的那个发送出去。然后再从之前选择的序列中读取一个新的元素,再重复执行这个步骤,直到所有的输入序列都耗尽为止。
4.16 用迭代器取代while循环
用iter()替代while,其中使用lambda可以创建一个不带参数的可调用对象。

第五章 文件和IO

5.1 读写文本数据
t是windows平台特有的所谓text mode(文本模式),区别在于会自动识别windows平台的换行符。rt模式下,python在读取文本时会自动把\r\n转换成\n;wt模式下,Python写文件时会用\r\n来表示换行。
默认情况下,文件的读取和写入采用的都是系统默认的文本编码方式,可以通过sys.getdefaulttencoding()来查询;open()函数提供一个可选的errors参数来处理错误
5.2 将输出重定向到文件中
将print()函数的输出重定向到一个文件中,只要加上file关键字参数即可。
5.3 以不同的分隔符或行结尾符完成打印
在print()函数中使用seq和end关键字参数来根据需要修改输出,而str.join()方法只能处理字符串,故前者更通用。
5.4 读写二进制数据
需要在二进制文件中读取或写入文本内容,确保要进行编码或解码操作,读取->解码decode,写入->编码encode
5.5 对已不存在的文件执行写入操作
通过使用open()函数中鲜为人知的x模式替代常见的w模式来解决。
5.6 在字符串上执行I/O操作
当出于某种原因需要模拟出一个普通文件时,使用io.StringIO()和io.BytesIO()来创建一个文件型对象,请注意io.StringIO()和io.BytesIO()实例是没有真正的文件描述符来对应的,因此无法工作在需要一个真正的系统级文件的代码环境中。
5.7 读写压缩的数据文件
类似open()函数,gzip.open()和bz2.open()所接受的参数与open()一样,也支持encoding、errors、newline等关键字参数;当写入压缩数据时,压缩级别可以通过compresslevel关键字参数指定。
5.8 对固定大小的记录进行迭代
利用iter()和functools.parital()来完成,对于文本文件,更多的是按行读取。
5.9 将二进制数据读取到可变缓冲区中
import 将二进制数据直接读取到一个可变缓冲区中,中间不经过任何拷贝环节,使用文件对象的readinto()方法即可;使用f.readinto()需要注意的是,必须总是检查它的返回值,即实际读取的字节数,如果字节数小于所提供的缓冲区大小,这可能表述数据被截断或遭到了破坏。使用内存映象(memoryview),使得可以对存在的缓冲区做切片操作,但是中间不涉及任何拷贝操作。
5.10 对二进制文件做内存映射
import os
import mmap
通过mmap将文件映射到内存后,能够以高效和优雅的方式对文件的内容进行随机访问,优于通过组合各种seek()、read()和write()调用来访问。
5.11 处理路径名
要操纵路径名,可以使用os.path模块中的函数。
5.12 检测文件是否存在
利用os.path模块来对文件做检测简单而直接,唯一需要注意的是关于权限的问题。
5.13 获取目录内容的列表
可以使用os.listdir()函数来获取目录中的文件列表;文件名的匹配,可以用glob或者fnmatch模块。
5.14 绕过文件名编码
os.listdir('.')和os.listdir(b'.')使用原始字节串列出文件名。
5.15 打印无法解码的文件名
def bad_filename(filename)
5.16 为已经打开的文件添加或修改编码方式
这么做可能会破坏终端上的输出。
5.17 将字节数据写入文本文件
I/O系统是以不同的层次来构建的。文本文件是通过在缓冲的二进制模式文件上添加一个Unicode编码/解码层来构建的。buffer属性简单地指向底层的文件。如果访问该属性,就可以绕开文本编码/解码层了。
5.18 将已有的文件描述符包装为文件对象
并非所有的文件模式都可以得到支持。
5.19 创建临时文件和目录
from tempfile import TemporaryFile
由TemporaryFile()创建的文件都是未命名的,而且在目录中也没有对应的条目,如果想解放这种限制,可以使用NamedTemporaryFile()函数来替代;要创建一个临时目录,可以使用tempfile.TemporaryDirectory()来实现。
5.20 同串口进行通信
对于串口通信来说,最好是使用pySerial包比较好import serial,请记住所有涉及串口的I/O操作都是二进制的,因此确保在代码中使用的字节而不是文本。
5.21 序列化Python对象
要将Python对象序列化为字节流,就可以保存到文件中、存储到数据库中或者通过网络连接进行传输,最常见的做法是使用pickle模块:
将某个对象存储到文件中:
data = ....
f = open('somefile', 'wb')
pickle.dump(data, f)
要将对象存储为字符串,可以使用pickle.dumps():
s = pickle.dumps(data)
要从字节流中重新创建出对象,使用pickle.load()或pickle.loads()函数。
某些特定类型的对象是无法进行pickle操作的。这些对象一般来说都会涉及某种外部系统状态,用户自定义的类有时候可以通过提供__getstate__()和__setstate__()方法来规避这些限制。

第六章 数据编码与处理(略读)

6.1 读写CSV数据
6.2 读写JSON数据
6.3 解析简单的XML文档
6.4 以增量方式解析大型XML文件
6.5 将字典转换为XML
6.6 解析、修改和重写XML
6.7 用命名空间来解析XML文档
6.8 同关系型数据库进行交互
6.9 编码和解码十六进制数字
6.10 Base64编码和解码
6.11 读写二进制结构的数组
6.12 读取嵌套型和大小可变的二进制结构
6.13 数据汇总和统计

第七章 函数

7.1 编写可接受任意数量参数的函数
要编写一个可以接受任意数量的位置参数的函数,可以使用以*开头的参数;如果要接受任意数量的关键字参数,可以使用**开头的参数。
7.2 编写只接受关键字参数的函数
如果将关键字参数放置在以*打头的参数或者是一个单独的*之后;当指定可选的函数参数时,keyword-only参数常常是一种提高代码可读性的好方法。
7.3 将元数据信息附加到函数参数上
参数注解的函数:
def add(x:int, y:int) -> int:
return x + y
函数注解只会保存在函数的__annotation__属性中。

7.4 从函数中返回多个值
要从函数中返回多个值,只要简单地返回一个元组即可。
7.5 定义带有默认参数的函数
定义带有默认参数的函数看似很容易,但其实并不像看到的那么简单。如果默认值是可变容器的话,比如说列表、集合或者字典,那么应该把None作为默认值;如果不打算提供一个默认值,只是想写代码来检测可选参数是否被赋予了某个特定的值可以使用_no_value。
7.6 定义匿名或内联函数
仅仅完成表达式求值的简单函数可以通过lamdba表达式来替代。尽管lambda表达式允许定义简单的函数,但它的局限性也很大。具体来说,只能指定一条单独的表达式,这个表达式的结果就是函数的返回值。 7.7 在匿名函数中绑定变量的值
lamdba表达式中x的值应该是在执行时确定的,执行时x的值是多少就是多少。如果希望匿名函数可以在定义的时候绑定变量,并保持值不变,那么可以将那个值作为默认参数实现。
7.8 让带有N个参数的可调用对象以较小的参数形式调用
如果需要减少函数的参数数量,应该使用functools.partial()。函数partial()允许给一个或多个参数指定固定的值,以此减少需要提供给之后调用的参数数量。partial()常常可用来调整其他库中用到的回调函数的参数签名。
7.9 用函数替代只有单个方法的类
有一个只定义了一个方法的类(除__init__()方法外),但是为了简化代码,希望能够只用一个简单的函数来替代。在许多情况下,只有单个方法的类可以通过闭包(closure)将其转换成函数。在许多情况下,会使用只有单个方法的类的唯一原因就是保存额外的状态给类方法使用。简单来说,闭包就是一个函数,但是它还保存着额外的变量环境,使得这些变量可以在函数中使用。闭包的核心特性就是它可以记住定义闭包时的环境。
7.10 在回调函数中携带额外的状态
正在编写需要使用回调函数的代码,但是希望回调函数可以携带额外的状态以便在回调函数内部使用。
7.11 内联回调函数
正在编写使用回调函数的代码,但是担心小型函数在代码中大肆泛滥,程序的控制流就会因此而失控,希望能有一种方法使代码看起来像一般的过程式步骤。
7.12 访问定义在闭包内的变量
一般来说,在闭包内层定义的变量对于外界来说完全是隔离的,但是可以通过编写存取函数并将它们作为函数属性附加到闭包上来提供对内层变量的访问支持。

第八章 类与对象

8.1 修改实例的字符串表示
要修改实例的字符串表示,可以通过定义__str__()和__repr__()方法来实现。
8.2 自定义字符串的输出格式
要自定义字符串的输出格式,可以在类中定义__format__()方法。
8.3 让对象支持上下文管理协议
要让对象能够兼容with语句,需要实现__enter__()和__exit__()方法。
8.4 当创建大量实例时如何节省内存
对于那些主要用作简单数据结构的类,通常可以在类定义中增加__slot__属性,以此来大量减少对内存的使用。
8.5 将名称封装到类中
与其依赖语言特性来封装数据,Python程序员们更期望通过命名规则来表达出对数据和方法的用途。第一个规则是任何以单下划线(_)开头的名字应该总是被认为只属于内部实现。以双下划线打头的名称会导致名称重整的行为。
8.6 创建可管理的属性
要自定义对属性的访问,一种简单的方式是将其定义为property。
8.7 调用父类中的方法
要调用父类中的方法,可以使用super()函数完成。

第十二章 并发

12.1 启动和停止线程
threading库可用来在单独的线程中执行任意的Python可调用对象;对于需要长时间运行的线程或者一直不断运行的后台任务,应该考虑将这些线程设置为daemon(即,守护线程);需要自己构建终止线程、给线程发信号、调整线程调度属性以及执行任何其他的高级操作;由于全局解析器锁(GIL)的存在,Python线程的执行模型被限制在任意时刻只允许在解析器中运行一个线程。基于这个原因,不应该使用Python线程来处理计算密集型的任务,因为在这种任务中我们希望在多个CPU核心上实现并行处理。
12.2 判断线程是否已启动
使用threading库中的Event对象进行线程同步;Event对象最好只用于一次性的事件。也就是说,创建一个事件,让线程等待事件被设置,然后一旦完成了设置,Event对象就被丢弃。如果线程打算一遍又一遍地重复通知某个事件,那最好使用Condition对象来处理。
12.3 线程间通信
也许将数据从一个线程发往另一个线程最安全的做法是使用queue模块中的Queue
12.4 对临界区加锁
要想让可变对象安全地用在多线程环境中,可以利用threading库中的Lock对象来解决。建议使用with语句,Lock对象可确保产生互斥的行为,也就是说同一时间只允许一个线程执行with语句块中的代码。with语句会在执行缩进的代码块时获取到锁,当控制流离开缩进的语句块时释放这个锁。
12.5 避免死锁
写一个多线程程序,线程一次需要获取不止一把锁,同时还要避免出现死锁:避免出现的一个解决方案就是给程序中的每个锁分配一个唯一的数字编号,并且在获取多个锁时只按照编号的升序方式来获取。为了避免死锁,所有的锁都必须使用前面给出的acquire()函数来获取。如果某些代码片段中是直接获取锁的,那么这个避免死锁的算法就不能奏效。
12.6 保存线程专有状态
有时候在多线程程序中,需要保存专属于当前运行线程的状态,可以通过threading.local()来创建一个线程本地存储对象。在这个对象上保存和读取的属性只对当前运行的线程可见,其他线程无法感知。
12.7 创建线程池
创建一个工作者线程池用来处理客户端连接,或者完成其他类型的工作,concurrent.futures库中包含有一个ThreadPoolExecutor类可用来实现这个目的。一般来说,应该避免编写那种允许线程数量无限增长的程序,尽管可以工作,但是无法阻止恶意用户对服务器发起拒绝服务攻击,从而导致服务器上创建大量的线程,耗尽了系统资源而崩溃。
12.8 实现简单的并行编程
concurrent.futures库中提供了一个ProcessPoolExecutor类,可用来在单独运行的Python解析器实例中执行密集型的函数。
12.9 如何规避GIL带来的限制
尽管Python完全支持多线程编程,但是在解释器的C语言实现中,有一部分并不是线程安全的,因此不能完全支持并发执行,需要重点强调的是,GIL只会对CPU密集型的程序产生影响,如果程序是在做I/O操作,比如处理网络连接,那么选择多线程技术常常是一个明智的选择,因为它们大部分时间都花在等待对方发起连接上,实际可以创建数以千个的Python线程。
要规避GIL的限制主要有两种常用的策咯:第一,如果完全使用Python来编程,可以使用multiprocessing模块来创建进程池,把它当做协处理器来使用;第二种方式是把重点放在C语言的扩展编程上,主要思想就是将计算密集型的任务转移到C语言中,使其独立于Python,在C代码中释放GIL。
12.10 定义一个Actor任务
actor模式是最古老也是最简单的用来解决并发和分布式计算问题的方法之一。
12.11 实现发布者/订阅者消息模式
可以使用订阅者/发布者模式来取代传统的任务或线程之间相互发送消息。
12.12 使用生成器作为线程的替代方案
使用生成器(协程)作为系统线程的替代方案来实现并发。
12.13 轮询多个线程队列
对于轮询问题,常用的解决方案中涉及一个鲜为人知的技巧,即利用隐藏的环回(loopback)网络连接。
12.14 在UNIX上加载守护进程
(略读)

第十三章 实用脚本和系统管理

13.1 通过重定向、管道或输入文件来作为脚本的输入
Python内置的fileinpute模块使得这一切变得简单
13.2 终止程序并显示错误信息
要让程序以这种方式终止,可以发出一个SystemExit异常,但要提供错误信息作为参数。
raise SystemExit('It failed!')
13.3 解析命令行选项
可以用argparse模块来解析命令行选型。
13.4 在运行时提供密码输入提示
Python的getpass模块可以使用。
13.5 获取终端大小
可以使用os.get_terminal_size()函数来办到
13.6 执行外部命令并获取输出
可以使用函数subprocess.check_output()来完成。
13.7 拷贝或移动文件和目录
shutil模块中有着可移植的函数实现。
13.8 创建和解包归档文件
shutil模块中有两个函数——make_archive()和unpack_archive()。
13.9 通过名称来查找文件
搜索文件可使用os.walk()函数;为了避免出现可能像././foo//bar这样的诡异路径,还要用到两个额外的函数来修正结果。第一个是os.path.abspath(),它接受一个可能是相对的路径并将其组成绝对路径的形式。第二个是os.path。normpath(),它会将路径修正为标准化形式,从而帮助解决像双反斜、多当前目录的多次引用等问题。
13.10 读取配置文件
想要读取以常见的.ini格式所编写的配置文件,可以使用configparser模块来读取配置文件。
13.11 给脚本添加日志记录
使用logging模块。
13.12 给库添加日志记录
给一个库添加日志功能,但又不希望它影响那些没有使用日志功能的程序:创建一个专用的日志对象并将其初始化。
13.13 创建一个秒表计时器
使用time模块。
13.14 给内存和CPU使用量设定限制
resource模块可以用来执行这样的任务,但只适用于UNIX系统。
13.15 加载Web浏览器
webbrowser模块可用来以独立于平台的方式加载浏览器。

第十五章 C语言扩展(比较复杂,略读)

TODO

About

供平时学习查询使用

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages