栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python入门(二十一)- 常见模块

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python入门(二十一)- 常见模块

二十一、常见模块

上一章介绍了Python模块的相关知识,在实际开发中,Python的很多功能都已经有了成熟的第三方实现,一般不需要开发者”重复造轮子“,当开发者需要完成某种功能时,通过搜索引擎进行搜索,通常可以找到第三方在Python中为该功能所提供的扩展模块。实际上,Python语言本身也内置了大量模块,对于常规的日期、时间、正则表达式、JSON支持、容器类等,Python内置的模块已经非常完备。
Python内置模块总是在不断更新中,本文只是起到抛砖引玉的作用

20.1 常用模块 20.1.1 sys模块

sys模块代表了Python解释器,主要用于获取和Python解释器相关的信息。
如下示例,查看sys模块包含的程序单元(包括变量、函数等)。

>>> import sys
>>> [e for e in dir(sys) if not e.startswith('_')]
['addaudithook', 'api_version', 'argv', 'audit', 'base_exec_prefix', 'base_prefix', 
'breakpointhook', 'builtin_module_names', 'byteorder', 'call_tracing', 'copyright', 
'displayhook', 'dllhandle', 'dont_write_bytecode', 'exc_info', 'excepthook', 
'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 
'get_asyncgen_hooks', 'get_coroutine_origin_tracking_depth', 'getallocatedblocks', 
'getdefaultencoding', 'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile', 
'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettrace', 
'getwindowsversion', 'hash_info', 'hexversion', 'implementation', 'int_info', 'intern',
 'is_finalizing', 'last_traceback', 'last_type', 'last_value', 'maxsize', 'maxunicode',
  'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 
  'platlibdir', 'prefix', 'ps1', 'ps2', 'pycache_prefix', 'set_asyncgen_hooks', 
  'set_coroutine_origin_tracking_depth', 'setprofile', 'setrecursionlimit', 
  'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout', 'thread_info', 
  'unraisablehook', 'version', 'version_info', 'warnoptions', 'winver']
>>>

不必记住所有的单元,通常时用到哪些模块就去查阅其对应的说明文档和参考手册。sys模块的参考页面.
大部分时候用不到sys模块里很冷僻的功能,本节只介绍sys模块中常用属性和函数。

  • sys.argv : 获取运行Python程序的命令行参数。其中sys.argv[0]通常指该Python程序,sys.argv[1]代表Python程序提供的第一个参数,sys.argv[2]代表第二个参数…以此类推。
  • sys.byteorder : 显示本地字节序的指示符。如果本地字节序时大端模式。则该属性返回big;否则返回little。
  • sys.copyright : 该属性返回与Python解释器相关的版权信息。
  • sys.executable : 该属性返回Python解释器在磁盘上的存储路径。
  • sys.flags : 该只读属性返回运行Python命令时指定的旗标。
  • sys.getfilesystemencoding() : 返回在当前系统中保存文件所用的字符集。
  • sys.getrefcount(object) : 返回指定对象的引用计算。前面介绍过,当object对象的引用计算为0时,系统会回收该对象。
  • sys.getrecursionlimit() : 返回Python解释器当前支持的递归深度,该属性可通过setrecursionlimit()方法重置。
  • sys.getswitchinterval() : 返回在当前Python解释器中线程切换的时间间隔,该属性可以通过setswitchinterval()函数改变。
  • sys.implementation:返回当前Python解释器的实现。
  • sys.maxsize: 返回Python整数支持的最大值。在32位平台上,该属性值位231-1;在64位平台上,该属性值为263-1.
  • sys.modules : 返回模块名和载入模块对应关系的字典。
  • sys.path : 该属性指定Python产找模块的路径列表。程序可通过修改该属性来动态增加Python加载模块的路径。
  • sys.platform : 返回Python解释器所在平台的标识符。
  • sys.stdin : 返回系统的标准输入流(类文件对象)
  • sys.stdout : 返回系统的标准输出流(类文件对象)
  • sys.stderr : 返回系统的错误输出流(类文件对象)
  • sys.version : 返回当前Python解释器的版本信息。
  • sys.winver : 返回当前Python解释器的主版本号。
    示例:
>>> import sys
>>> print(sys.argv)
['']
>>> print(sys.copyright)
Copyright (c) 2001-2021 Python Software Foundation.
All Rights Reserved.

Copyright (c) 2000 BeOpen.com.
All Rights Reserved.

Copyright (c) 1995-2001 Corporation for National Research Initiatives.
All Rights Reserved.

Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
All Rights Reserved.
>>> print(sys.executable)
D:Administrator5-PersonalSoftwarepython-3.9.9-embed-amd64python.exe
>>> print(sys.getfilesystemencoding())
utf-8
>>>
20.1.2 os模块

os模块代表了程序所在的操作系统,主要用于获取程序运行所在操作系统的相关信息。
在Python交互解释器中先导入os模块,使用all命令查看该模块对外开放的全部属性和函数。示例如下:

>>> import os
>>> os.__all__
['altsep', 'curdir', 'pardir', 'sep', 'pathsep', 'linesep', 'defpath', 'name', 'path', 
'devnull', 'SEEK_SET', 'SEEK_CUR', 'SEEK_END', 'fsencode', 'fsdecode', 'get_exec_path', 
'fdopen', 'popen', 'extsep', '_exit', 'DirEntry', 'F_OK', 'O_APPEND', 'O_BINARY', 
'O_CREAT', 'O_EXCL', 'O_NOINHERIT', 'O_RANDOM', 'O_RDONLY', 'O_RDWR', 'O_SEQUENTIAL', 
'O_SHORT_LIVED', 'O_TEMPORARY', 'O_TEXT', 'O_TRUNC', 'O_WRONLY', 'P_DETACH', 'P_NOWAIT', 
'P_NOWAITO', 'P_OVERLAY', 'P_WAIT', 'R_OK', 'TMP_MAX', 'W_OK', 'X_OK', 'abort', 'access', 
'chdir', 'chmod', 'close', 'closerange', 'cpu_count', 'device_encoding', 'dup', 'dup2', 
'environ', 'error', 'execv', 'execve', 'fspath', 'fstat', 'fsync', 'ftruncate', 
'get_handle_inheritable', 'get_inheritable', 'get_terminal_size', 'getcwd', 'getcwdb', 
'getlogin', 'getpid', 'getppid', 'isatty', 'kill', 'link', 'listdir', 'lseek', 'lstat', 
'mkdir', 'open', 'pipe', 'putenv', 'read', 'readlink', 'remove', 'rename', 'replace', 
'rmdir', 'scandir', 'set_handle_inheritable', 'set_inheritable', 'spawnv', 'spawnve', 
'startfile', 'stat', 'stat_result', 'statvfs_result', 'strerror', 'symlink', 'system', 
'terminal_size', 'times', 'times_result', 'truncate', 'umask', 'uname_result', 'unlink', 
'unsetenv', 'urandom', 'utime', 'waitpid', 'waitstatus_to_exitcode', 'write', 'makedirs',
 'removedirs', 'renames', 'walk', 'execl', 'execle', 'execlp', 'execlpe', 'execvp', 
 'execvpe', 'getenv', 'supports_bytes_environ', 'spawnl', 'spawnle']
 
>>>

同样不需要记住所有的函数,os模块主要包含3方面的内容:

  1. 系统相关的函数
方法说明
os.name返回导入依赖模块的操作系统名称,通常可返回’posix’,‘nt’,'java’等值其中之一
os.environ返回在当前系统上所有环境变量组成的字典
os.fsencode(filename)该函数对类路径(path-like)的文件名进行编码
os.fsdecode(filename)该函数对类路径(path-like)的文件名进行解码
os.PathLike这是一个类,代表一个类路径(path-like)对象
os.getenv(Key,default=None)获取指定环境变量的值
os.getlosin()返回当前系统的登录用户名。与该函数对应的还有os.getuid(),os.getgroups(),os.getgid()等函数,用于获取用户ID,用户组,组ID等,这些函数通常只在UNIX系统上有效
os.getpid获取当前进程ID
os.getppid获取当前进程的父进程ID
os.putenv(key,value)该函数用于设置环境变量
os.cpu_count()返回当前系统的cpu数量
os.sep返回路径分隔符
os,pathsep返回当前系统上多条路径之间的分隔符,一般在Windows系统上多条路径之间的分隔符是英文分号(;);在UNIX及类UNIX系统上多条路径分隔符是英文冒号(:)
os.linesep返回当前系统的换行符。WIndows为’rn’;UNIX’为’n’;Mac OS X为’r’
os.urandom(size)返回时和作为加密使用的、最多由N个字节组成的bytes对象。该函数通过操作系统特定的随机性来源返回随机字节,该随机字节通常是不可预测的,因此适用于绝大部分加密场景

下面程序演示了表 1 中部分函数的功能和用法:

>>> import os
>>> os.name
'nt'
>>> os.getenv('PYTHONPATH')
>>> os.getlogin()
'F21633C'
>>> os.getpid()
13676

其他的示例就不一一试验了,感兴趣的读者可以自己尝试。

  1. 文件相关的函数
    具体的用法我们还会在后续文件操作中进行介绍。
方法说明
os.path.abspath(path)返回 path 的绝对路径。
os.path.basename(path)获取 path 路径的基本名称,即 path 末尾到最后一个斜杠的位置之间的字符串。
os.path.commonprefix(list)返回 list(多个路径)中,所有 path 共有的最长的路径。
os.path.dirname(path)返回 path 路径中的目录部分。
os.path.exists(path)判断 path 对应的文件是否存在,如果存在,返回 True;反之,返回 False。和 lexists() 的区别在于,exists()会自动判断失效的文件链接(类似 Windows 系统中文件的快捷方式),而 lexists() 却不会。
os.path.lexists(path)判断路径是否存在,如果存在,则返回 True;反之,返回 False。
os.path.expanduser(path)把 path 中包含的 “~” 和 “~user” 转换成用户目录。
os.path.expandvars(path)根据环境变量的值替换 path 中包含的 “ n a m e " 和 " name" 和 " name"和"{name}”。
os.path.getatime(path)返回 path 所指文件的最近访问时间(浮点型秒数)。
os.path.getmtime(path)返回文件的最近修改时间(单位为秒)。
os.path.getctime(path)返回文件的创建时间(单位为秒,自 1970 年 1 月 1 日起(又称 Unix 时间))。
os.path.getsize(path)返回文件大小,如果文件不存在就返回错误。
os.path.isabs(path)判断是否为绝对路径。
os.path.isfile(path)判断路径是否为文件。
os.path.isdir(path)判断路径是否为目录。
os.path.islink(path)判断路径是否为链接文件(类似 Windows 系统中的快捷方式)。
os.path.ismount(path)判断路径是否为挂载点。
os.path.join(path1[, path2[, …]])把目录和文件名合成一个路径。
os.path.normcase(path)转换 path 的大小写和斜杠。
os.path.normpath(path)规范 path 字符串形式。
os.path.realpath(path)返回 path 的真实路径。
os.path.relpath(path[, start])从 start 开始计算相对路径。
os.path.samefile(path1, path2)判断目录或文件是否相同。
os.path.sameopenfile(fp1, fp2)判断 fp1 和 fp2 是否指向同一文件。
os.path.samestat(stat1, stat2)判断 stat1 和 stat2 是否指向同一个文件。
os.path.split(path)把路径分割成 dirname 和 basename,返回一个元组。
os.path.splitdrive(path)一般用在 windows 下,返回驱动器名和路径组成的元组。
os.path.splitext(path)分割路径,返回路径名和文件扩展名的元组。
os.path.splitunc(path)把路径分割为加载点与文件。
os.path.walk(path, visit, arg)遍历path,进入每个目录都调用 visit 函数,visit 函数必须有 3 个参数(arg, dirname, names),dirname 表示当前目录的目录名,names 代表当前目录下的所有文件名,args 则为 walk 的第三个参数。
os.path.supports_unicode_filenames设置是否可以将任意 Unicode 字符串用作文件名。
  1. 进程管理函数
    主要用于启动新进程、中止已有进程等
方法说明
os.abort()生成一个SIGABRT(硬件异常终止)信号给当前进程。在UNIX系统上,默认行为是生成内核转储;在Windows系统上,进程立即返回退出代码3
os.execl(path,arg0,arg1,…)该函数还有一系列功能历史的函数,比如os.execle(),os.execlp()等,这些函数都是适用参数列表arg0,arg1,…来执行path所代表的执行文件的
os.forkpty()fork一个子进程
os.kill(pid,sig)将sig信号发送到gid对应的进程,用于结束该进程
os.kill(pgid,sig)将sig信号发送到pgid对应的进程组
os.popen(cmd,mode=‘r’,buffering=-1用于向cmd命令打开读写管道(当mode=r时为只读,mode=rw时为读写,buffering缓冲参数与内置的open()函数有相同的含义。该函数返回的文件对象用于读写字符串,而不是字节。
os.spawnl(mode,path,…)此函数还有一系列功能类似的函数,比如os.spawnle(),os.spawnlp()等,这些函数都用于在新进程中执行新程序
os.startfile(path[,operation])对指定文件适用该文件关联的工具执行operation对应的操作,如果不指定operation操作,则默认执行打开(open)操作。operation参数必须是有效的命令行操作项目,比如open(),edit(),print()等
os.system(command)运行操作系统上的指定命令
示例如下:
import os
# 运行平台cmd命令
# **os.system('cmd')**
# 使用Excel打开g:\abc.xls文件
os.startfile('g:\abc.xls')
os.spawnl(os.P_NOWAIT,'E:\Tools\Notepad++.7.5.6.bin.x64\notepad++.exe','')
# 使用python命令执行os_test.py程序
os.execl("D:\Python\Python36\Python.exe","","os_test.py",'i')

如果直接运行上面的程序,可以看到程序运行后使用Excel打开了abc.xls文件,也打开了Notepad++工具,还使用python命令运行了os_test.py文件。但如果将程序中**包裹的代码启用,将看到程序运行后只启动了cmd命令,这是因为使用os.system()函数来运行程序,新程序所在的进程会替代原有进程。
在使用os.execl()函数运行新进程之后,也会取代原有的进程,因此上面程序将这行代码放在了最后。

20.1.3 random模块

random模块主要包含生成伪随机数的各种功能变量和函数,我们还是先来看一下它都包含哪些函数。

>>> import random
>>> random.__all__
['Random', 'SystemRandom', 'betavariate', 'choice', 'choices', 'expovariate', 
'gammavariate', 'gauss', 'getrandbits', 'getstate', 'lognormvariate', 'normalvariate', 
'paretovariate', 'randbytes', 'randint', 'random', 'randrange', 'sample', 'seed', 
'setstate', 'shuffle', 'triangular', 'uniform', 'vonmisesvariate', 'weibullvariate']
>>>
方法说明
random.seed(a=None,version=2)指定种子来初始化伪随机数生成器
random.randrange(start,stop[,step])返回从start开始到stop结束,步长为step的随机数,其实就相当于choice(range(start,stop,step))的效果,只不过实际底层并不生成区间对象
random.randint(a,b)生成一个方位为a<=N<=b的随机数,其等同于randrange(a,b+1)的效果
random.choice(seq)从seq中随机抽取一个元素,如果seq为空,则引发IndexError异常
random.choices(seq,weights=None,*,cum_weights=None,k=1)从seq序列中抽取k个元素,还可通过weights指定各元素被抽取的权重(被抽取的可能性高低)
random.shuffle(x[,random])对x序列执行洗牌,随机排列操作
random.sample(population,k)从population序列中随机抽取k个独立元素
random.random()生成一个从0.0(包含)开始到1.0(不包含)之间的伪随机浮点数
random.uniform(a,b)生成一个范围为a<=N<=b的随机数
random.expovariate(lambd)生成一个呈指数分布的随机数,其中lambd参数(其实应该使lambda,只是lambda是关键字)为1除以期望平均值。如果lambd是正值,则返回的随机数从0至正无穷,为负值,返回从负无穷到0
20.1.4 time模块

time模块主要包含各种提供日期、时间功能的类和函数,该模块既提供了把日期、时间格式化为字符串的功能,也提供了从字符串恢复日期、时间的功能。

>>> import time
>>> [e for e in dir(time) if not e.startswith('_')]
['altzone', 'asctime', 'ctime', 'daylight', 'get_clock_info', 'gmtime', 'localtime', 'mktime', 'monotonic', 'monotonic_ns', 'perf_counter', 'perf_counter_ns', 'process_time', 'process_time_ns', 'sleep', 'strftime', 'strptime', 'struct_time', 'thread_time', 'thread_time_ns', 'time', 'time_ns', 'timezone', 'tzname']
>>>

在time模块内提供了一个time.struct_time类,该类代表一个时间对象,它主要包含9个属性,每个属性的信息如下:

字段名字段含义
tm_year如2017、2018等
tm_mon如2,3等,范围1~12
tm_mday如2,3等,范围1~31
tm_hour如2,3等,范围1~23
tm_min如2,3等,范围0~59
tm_sec如2,3等,范围0~59
tm_wday周一为0,范围0~6
tm_yday一年内的第几天如65等,范围1~366
tm_isdst夏令时0,1或-1
比如,Python可以用time.struct_time(tm_year=2022,tm_mon=7,tm_mday=8,tm_hour=14,tm_min=4,tm_sec=45,tm_wday=4,tm_yday=1,tm_isdst=0)很清晰地代表时间。
此外,Python还可以用一个包含9个元素的元组来代表时间,该元组的9个元素和struct_time对象中9个属性的含义是一一对应的,比如程序可以使用(2022,7,8,14,4,45,4,1,0)来代表时间。
在日期、时间模块内常用的功能函数如下:
方法说明
time.asctime([t])将时间元组或struct_time转换为时间字符串。如果不指定参数t,则默认转换当前时间
time.ctime([secs])将以秒数代表的时间转换为时间字符串,从1970年1月1日0点开始计算,由于时区问题,中国处于东八区,实际上从1970年1月1日8:00开始计算
time.gmtime([secs])将以秒数代表的时间转换为struct_time对象,如果不传入参数,则使用当前时间(格林尼治时间)
time.localtime([secs])将以秒数代表的时间转换为代表当前时间的struct_time对象,如果不传入参数,则使用当前时间(本地时间,东八区)
time.mktime(t)他是localtime的反转函数,用于将struct_time对象或元组代表的时间转换为从1970.1.1日0点到现在的秒数
time.perf_counter()返回性能计数器的值,单位秒
time.process_time()返回当前进程使用CPU的时间,单位秒
time.sleep(secs)暂停secs秒,什么都不干
time.strftime(format[,t])将时间元组或struct_time对象格式化为指定格式的时间字符串,如果不指定参数t,则默认转换当前时间
time.strptime(string[,format])将字符串格式的时间解析成struct_time对象
time.time()返回从1970.1.1日0点到现在过来多少秒
time.timezone返回本地时区的时间偏移,单位秒
time.tzname返回本地时区的名字
示例:
>>> time.localtime()
time.struct_time(tm_year=2022, tm_mon=7, tm_mday=8, tm_hour=15, tm_min=7, tm_sec=44, tm_wday=4, tm_yday=189, tm_isdst=0)
>>> time.gmtime()
time.struct_time(tm_year=2022, tm_mon=7, tm_mday=8, tm_hour=7, tm_min=8, tm_sec=18, tm_wday=4, tm_yday=189, tm_isdst=0)
>>>

time.srftime()与time.strptime()涉及到编写格式模板,时间格式字符串支持的指令如下:

指令含义
%a本地化的星期几的缩写名,比如Sun代表星期天
%A本地化星期几的完整名
%b本地化月份的缩写名,比如Jan代表表一月
% B本地化月份的完整名
% c本地化的日期和时间的表示形式
% d代表一个月中第几天的数值,范围:01-31
% H代表24小时制的小时,范围:00-23
% I代表12小时制的小时,范围:01-12
% j一年中第几天,范围:001-366
% m代表月份的数值,范围:01-12
%M代表分钟的数值,范围:00-59
% p上午或下午的本地化方式,当使用strptime()函数并使用%I指令解析小时时,%p只影响小时字段
%S代表分钟的数值,范围:00-61,60在表示闰秒的时间戳时有效,61则是由于一些历史原因造成的
%U代表一年中的第几周,以星期天为每周第一天,范围:00-53,在这种方式下,一年中第一个星期天被认为处于第一周,当使用strptime()函数解析时间字符串时,只有何时指定了星期几和年份该指令才生效
%w代表星期几的数值,范围:0-6,其中0代表周日
% W代表一年中第几周,以星期一为每周的第一天,范围:00-53,在这种方式下,一年中第一个星期一被任务处于第一周,当使用strotime()函数解析时间字符串时,只有同时指定了星期几和年份,该指令才生效
%x本地化的提起表示形式
% X本地化时间表示形式
% y年份的缩写,范围:00-99.比如2018简写成18
%Y年份的完整形式
% z显示时区偏移
% Z时区名
% %代表%
20.1.5 itertools模块(函数相关)

在itertools模块中,主要包含了一些生成迭代器的函数,

>>> import itertools
>>> [e for e in dir(itertools) if not e.startswith('_')]
['accumulate', 'chain', 'combinations', 'combinations_with_replacement', 'compress', 
'count', 'cycle', 'dropwhile', 'filterfalse', 'groupby', 'islice', 'permutations', 
'product', 'repeat', 'starmap', 'takewhile', 'tee', 'zip_longest']
>>>
  1. 生成无限迭代器
  • count(start,[step]):生成start开始,步进为step(默认1)的迭代器,
  • cycle§:生成序列p无限循环的迭代器,
  • repeat(elem[,n]):生成n个元素elem重复的迭代器,不指定n,则生成无限循环。
  1. 其他常用迭代器函数
  • accumulate(p[,func]):生成按照func函数计算序列p内元素形成的迭代器,如果不指定func,默认生成序列p元素累加迭代器,p0,p0+p1,p0+p1+p2,…
  • chain(p,q,…):将多个序列元素”链“在一起,形成新的迭代器
  • compress(data,selectors):根据selectors序列的值对data序列的元素进行过滤,如果selectors[0]的值为真,保留data[0],否则删除,以此类推。
  • dropwhile(pred,seq):使用pred函数对seq序列进行过滤,保留从第一个计算为False的元素seq[i]开始至结束的元素。
  • takewhile(pred,seq):与上一函数相反,去掉从第一个计算结果为False的seq[i]至结束的元素
  • filterfalse(pred,seq):保留序列seq中,使用pred计算结果为True的值
  • islice(seq,[start,]stop[,step]):类似于序列的切片slice()函数,返回seq[start:stop:step]的结果
  • starmap(func,seq):使用func()对seq的元素进行计算,返回计算结果的迭代器,支持序列解包,即seq中多个元素给func传递参数,输出结果。所以变换后的序列长度未必等于len(seq)
  • zip_longers(p,q,…)将p,q等序列中的元素按索引合并成元组,这些元组将作为新学列的元素。
  1. 生成排列组合的工具函数
  • product(p,q,…[repeat=1]):用学了p,q中的元素进行排列组合,相当于使用嵌套循环组合。
  • permutations(p,[,r]):从序列p中取出r个元素组成全排列,将排列得到的元组作为新迭代器的元素
  • combinations(p,r):从序列p中取出r个元素组成全组合,元素不允许重复,将组合得到的元组作为新迭代器的元素
  • conbinations_with_replacement(p,r):从序列p中取出r个元素组成全组合,元素允许重复,将组合得到的元组作为新迭代器的元素。
    示例:
import itertools as it
#product 使用两个序列进行排列组合
for e in it.product('AB','CD'):
    print(''.join(e),end=',')    # AC, AD, BC, BD,
#product 使用一个序列,重复两次进行排列组合
for e in it.product('AB',repeat=2):
    print(''.join(e),end=',')    # AA, AB, BA, BB,
>>> [e for e in it.permutations('ABCD',2)]
[('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'A'), ('B', 'C'), ('B', 'D'), ('C', 'A'), ('C', 'B'), ('C', 'D'), ('D', 'A'), ('D', 'B'), ('D', 'C')]
>>> [e for e in it.combinations('ABCD',2)]
[('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D')]
>>> [e for e in it.combinations_with_replacement('ABCD',2)]
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'B'), ('B', 'C'), ('B', 'D'), ('C', 'C'), ('C', 'D'), ('D', 'D')]
>>>

20.1.6 functools模块

functools模块中主要包含了一些函数装饰器和便捷的功能函数。

>>> import functools
>>> [e for e in dir(functools) if not e.startswith('_')]
['GenericAlias', 'RLock', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES', 'cache', 
'cached_property', 'cmp_to_key', 'get_cache_token', 'lru_cache', 'namedtuple', 'partial', 
'partialmethod', 'recursive_repr', 'reduce', 'singledispatch', 'singledispatchmethod', 
'total_ordering', 'update_wrapper', 'wraps']
>>>
  • functools.lru_cache(maxsize=128,type=False): 该函数装饰器使用LRU(最近最少使用)缓存算法来缓存相对耗时的函数结果,避免传入相同的参数重复计算。同时,缓存并不会无限增长,不用的缓存会被释放。其中,maxsize参数用于设置缓存只占用的最大字节数。typed参数用于设置将不同类型的缓存结果分开存放
  • functools.cmp_to_key(func):将func转换为关键字函数
  • @functools.total_ordering:这个类装饰器(作用类似于函数装饰器,只是它用于装饰类)用于为类自动生成比较方法。通常来说,开发者只要提供–lt–()-、–le–()-、–gt–()-、–ge–()其中之一(最好能提供–eq–()方法),@functools.total_ordering装饰器就会为该类生成剩下的比较好的方法。
  • functools.partial(func,*args,**keywords):该函数用于为func函数的部分参数指定参数值,从而得到一个转换后的函数,程序以后调用转换后的函数时,就可以少传入哪些已指定值的参数。
  • functools.partialmethod(func,*args,**keywords):该函数与上一函数含义完全相同,只不过该函数用于为类中的方法设置参数
  • functools.reduce(function,iterable[,initialzer]):将初始值(默认为0,可由initialzer参数指定)、迭代器的当前元素传入function函数,将计算出来的函数结果作为下一次计算的初始值、迭代器的下一元素再次调用function函数,以此类推,直到迭代器的最后一个元素。
  • @functools.singledispatch:该函数装饰器用于实现函数对多个类型进行重载。比如同样的函数名称,为不同的参数类型提供不同的功能实现,该函数的本质就是根据参数类型的变换,将函数转向调用不同的函数。
  • functools.update_wrapper(wrapper,wrapped,assigned=WRAPPER_ASSIGNMENTS,updated=WRAPPER_UPDATES):对wrapper函数进行包装,使之看上去就像wrapper(被包装)函数。
  • functools.wraps(wrapped,assigned=WRAPPER_ASSIGNMETS,updated=WRAPPER_UPDATES):该函数装饰器用于修饰包装函数,使包装函数看上去就像wrapper函数。
from functools import *
#设初始值(默认为0)为x,当序列元素为y,将x+y作为下一次初始值
print(reduce(lambda x,y:x+y,range(5)))  #10
print(reduce(lambda x,y:x+y,range(6)))   #15
#设初始值为10
print(reduce(lambda x,y:x+y,range(6),10))   +25

class User:
    def __init__(self,name)
        self.name = name
    def __repr__(self)
        return 'User[name]=%s'% self,name
#定义一个老式的大小比较函数,User的那么越长,该User越大
def old_cmp(u1,u2)
    return len(u1.name)-len(u2.name)
my_data = [User('kotlin'),User('Swift'),User('Go'),User('Java')]
# 对my_data排序,需要将关键字函数(调用cmp_to_key将old_cmp转换为关键字函数)
my_data.sort(key=cmp_to_key(old_cmp))
Print (my_data)  

@lru_cache(maxsize=32)
def factorial(n):
    print(’计算 %d 的阶乘',%n)
    if n==1:
        return 1
    else:
        return n*factorial(n-1)
#只有这行会计算,然后会缓存5、4、3、2、1的阶乘
print(factorial(5))
print(factorial(3))
print(factorial(5))

#内置函数int函数默认将十进制的字符串转换为整数
print(int('1234')
# 为int函数的base参数指定参数值
basetwo = partial(int,base =2 )
basetwo.__doc__ = '将二进制形式的字符串转换为整数'
#相当于执行base=2的int函数(将二进制的字符串转为十进制)
print(basetwo('10010'))    #18
print(int('10010',2))    #18

partialmethod()与partial()函数的作用基本相似,只是用于类方法部分参数值绑定。

from functools import *
class Cell:
    def __init__(self):
        self.alive = False
    # @property装饰器指定该方法可使用属性语句访问
    @property
    def alive(self):
        return self._alive
    def set_state(self,state):
        self.alive = bool(state)
    #指定set_alive()方法,就是将set_state()方法的state参数指定为Ture
    set_alive = partialmethod(set_state,Ture)
    #指定set_dead()方法,就是将set_state()方法的state参数指定为False
    set_dead = partialmethod(set_state,False)
c = Cell()
print(c.alive) # False
#相当于调用c.set_state(Ture)
c.set_alive()
print(c.alive)   # Ture
#相当于调用c.set_state(False)
c.set_alive()
print(c.alive)   # False

下面示范@total_ording类装饰器的作用。

from functools import *
@total_ordering
class User:
    def __init__(self,name):
        self.name = name
    def __repr__(self):
        return 'User|name=%s'% self.name
    #根据是否有name属性决定是否可比较
    def _is_valid_operand(self,other):
        #内置函数hasattr()判断other对象中是否有name属性
        rentrn hasattr(other,"name")
    def __eq__(self,other):
        if not self._is_valid_operaned(other)
            return NotImplemented
        #根据name判断是否相等(都转换成小写比较,或略大小写)
        return self.name.lower() == other.lastname.lower()
    def __lt__(self,other):
        if not self._is_valid_operaned(other)
            return NotImplemented
        #根据name判断是否小于(都转换成小写比较,或略大小写)
        return self.name.lower() < other.lastname.lower()
#打印被装饰之后的User类中的__gt__方法
print(User.__gt__)   #自动生成了大于的比较

@singledispatch函数装饰器的作用使根据函数参数类型,实现调用不同的函数。

from functools import *
@singledispatch
def test(are,verbose):
    if verbose:
        print('默认参数为:',end = "")
    print(arg)
#限制test函数的第一个参数为int类型的函数版本,register()方法是使用@singledispatch修饰后,自动添加的方法,用于为指定类型注册被转向调用的函数。
@test.register(int)
def (argu,verbose):
    if verbose:
        print('整型参数为:',end = "")
    print(argu)
test('Python',True)   #默认参数为:Python
test(20,True)        #整型参数为:20
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1009687.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号