# sys

这个模块代表了Python解释器,用于获取和Python解释器相关的信息。官方文档

import sys
# 获取命令行参数
print(sys.argv)
# 查看Python解释器在磁盘上的路径
print(sys.executable)
# 查看一个引用的计数
class MyObj:pass
o1 = MyObj()
o2 = o1 
print(sys.getrefcount(o1))
# 查看当前系统中保存文件所用的字符集
print(sys.getfilesystemencoding())
# 查看Python path
print(sys.path)
# 查看模块和载入模块对应关系的字典
print(sys.modules)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# os

os模块代表了操作系统,用于获取和操作系统有关信息。官方文档

import os
# 查看操作系统的名字
print(os.name)
# 查看操作系统所有环境变量
print(os.environ)
# 获取指定环境变量
print(os.getenv("Path"))
# 获取当前系统的CPU数量
print(os.cpu_count())
# 获取当前登录用户
print(os.getlogin())
1
2
3
4
5
6
7
8
9
10
11

# random

random模块包含生成伪随机数的各种功能变量和函数。官方文档

import random
# 生成0到1之间的随机数
print(random.random())
# 生成2到8之间的随机数
print(random.uniform(2,8))
# 生成0到10之间的随机偶数
print(random.randrange(0,11,2))
# 从列表中中随机抽取一个
MyList=["Python","hello","world","New"]
print(random.choice(MyList))
# 按照权重抽取
print(random.choices(MyList,[3,3,1,1],k=10))
# 排序列表
random.shuffle(MyList)
print(MyList)
# 随机抽取2个独立元素
print(random.sample(MyList,2))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# math

import math
print("指数运算:%s" % math.pow(2,3))
print("floor舍掉:%s" % math.floor(2.23434))
print("ceil舍掉:%s" % math.ceil(232.232))
print("转换为弧度:%s" % math.radians(180))
print("sin值:%s" % math.sin(math.pi/2))
min(2,3)
max(2,5,6)
sum([10,12,43])
divmod(10,3)
1
2
3
4
5
6
7
8
9
10

# time

time模块提供日期,时间功能的类和函数。官方文档

Python内部表示时间的类:

class _struct_time(NamedTuple):
    tm_year: int
    tm_mon: int
    tm_mday: int
    tm_hour: int
    tm_min: int
    tm_sec: int
    # 一周中的第几天
    tm_wday: int
    # 一年中的第几天
    tm_yday: int
    # 是否是夏令时
    tm_isdst: int
    # 时区
    tm_zone: str
    tm_gmtoff: int
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Python的time模块相关函数:

import time
# 将当前时间打印出来
print(time.asctime())
# 将时间元组转换成可读形式
print(time.asctime((2020,4,28,13,0,30,0,0,0)))
# 将时间戳转换成可读形式:从1970年1月1日0点开始计算的秒数,会受时区影响。
print(time.ctime(1000))
# 将时间戳转换成UTC时区(0时区)的struct_time
print(time.gmtime())
# 将时间戳转换为本地时区的struct_time
print(time.localtime())
# 将元组格式的时间转换为时间戳
print(time.mktime((2020,4,28,14,43,0,0,0,0)))
# 返回性能计数器的值,以秒为单位,可以用来计算几条指令之间的持续时间
beginTime=time.perf_counter()
print("beginTime:%s" % beginTime)
print("hello world")
print(time.perf_counter()-beginTime)
# 返回当前进程使用CPU的时间,以秒为单位。
print(time.process_time())
# 暂停1秒
time.sleep(1)
print("hi")
# 将当前时间转换为指定格式字符
import locale
locale.setlocale(locale.LC_CTYPE, 'chinese')
print(time.strftime('%Y年%m月%d日 %H时%M分%S秒'))
# 将指定时间转换为struct_time对象
print(time.strptime("2020年4月28日","%Y年%m月%d日"))
# 返回当前时间戳
print(time.time())
# 返回本地时区的时间偏移,以秒为单位
print(time.timezone)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# JSON

JSON是一种轻量级,跨平台,跨语言的数据交换格式,最常见的应用是Web后台数据交换。它的全称是JavaScript Object Notation,该格式既适合人来读写也适合计算机本身解析,它最早起源于JavaScript,后来变成和语言无关的通用格式,它主要有以下两种格式:

  1. 由key-value组成的数据结构。
  2. 有序集合。

JSON中Python类型和JavaScript类型对应关系

JavaScript Python
对象(object) 字典(dict)
数组(array) 列表(list),元组(tuple)
字符串(string) 字符串(str)
整数(number) 整数(int),浮点型(float)
实数(number) 浮点数(float)

json在Python中的操作:

import json
f = open("test.json","w")
# 将Python对象转换为json字符串写入到文件中
json.dump(["person",{"name":"li"}],f)
f.close()
# 将f中内容转换为Python对象
PythonObj = json.load(open("test.json"))

# 将Python对象转换为json字符串
jsonStr1=json.dumps(["li",{"age":13}])
print(type(jsonStr1))
print(jsonStr1)

# 将json字符串转换回Python对象
PythonObj1 = json.loads(jsonStr1)
print(type(PythonObj1))

# 第二种方法转换Python对象为json字符串
jsonStr2=json.JSONEncoder().encode({"name":"li","age":28})
print(type(jsonStr2))
print(jsonStr2)
# 将json字符串按一定规则转换回Python对象
def changeJsonToPython(target):
    if target["name"]=="li":
        return target["age"]
PythonObj2=json.loads(jsonStr2,object_hook=changeJsonToPython)
print(type(PythonObj2))
print(PythonObj2)


# 将Python字典转换为json字符串,并根据键排列顺序
print(json.dumps({"a":1,"d":2,"c":3,"b":4},sort_keys=True))
# 替换分隔符
print(json.dumps({"a":1,"d":2,"c":3,"b":4},separators=('`',':')))
# 对json字符串进行缩进
print(json.dumps({"a":1,"d":2,"c":3,"b":4},indent=4))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

笔者注意到官方文档有这样一个例子:

import json
class ComplexEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, complex):
            return [obj.real, obj.imag]
        # Let the base class default method raise the TypeError
        return json.JSONEncoder.default(self, obj)

s2=json.dumps(1+2j, cls=ComplexEncoder)
print(s2)
1
2
3
4
5
6
7
8
9
10

于是仿照它写了这样一个例子:

import json
class MyEncoder(json.JSONEncoder):
    def default(self,obj):
        print("hi")
        if isinstance(obj,dict):
            print("it is dict!")
            return obj["name"]
        return json.JSONEncoder.default(self,obj)

print(MyEncoder().encode({"name":"sun","age":40}))
jsonStr=json.dumps({"name":"wang","age":30},cls=MyEncoder)
print(jsonStr)
1
2
3
4
5
6
7
8
9
10
11
12

发现这个例子并没有按照上面那个例子的思路运行,查阅官方文档说明只有对象是不能被序列化成json的时候才会调用default,否则就直接返回这个对象。

# 正则表达式

正则表达式(Regular Expression)用于描述一组字符串的特征,也可被称为模式(Pattern),实现的效果是可检查一个字符串是否含有某个子串,从该字符串中提取匹配的子串,或者对这些子串执行替换功能。来看基本操作:

import re

# 先编译正则表达式再匹配
# 返回第一处匹配的位置的相关信息
p=re.compile('123')
result=p.search('hello.123,123')
print(result.span())
print(result.group())

# 直接匹配
result=re.search('123','hello.123,123')
print(result.span())
print(result.group())

# 从字符串开头匹配
result=re.match('123','123,123.hello')
print(result.span())
print(result.group())

# 查找所有字符串,忽略大小写
result=re.findall('abc','w.abc,abc.hello.Abc',re.I)
print(result)

# 查找所有字符串,忽略大小写,并返回相关信息
result=re.finditer('abc','w.abc,abc.hello.Abc',re.I)
for e in result:
    print(str(e.span())+"  :  "+str(e.group()))

# 查看整个字符串是否匹配
result=re.fullmatch("abc","AbC",re.I)
print(result.group())

# 替换字符串,替换次数最多为2次
targetStr="abc,Abc,ABc"
result=re.sub("abc","AbC",targetStr,2,re.I)
print(targetStr)
print(result)

# 通过正则表达式对字符串进行切割
result=re.split("abc","hello,Abc,this a string named abC,can you help it to be AbC?",10,re.I)
print(result)

# 对模式中除ASCII码,数值,下划线之外的其他字符转义
print(re.escape("hello-world-"))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

Python中负责正则表达式的是re模块,该模块中包含两个大类,一个是正则表达式对象_sre.SRE_Pattern。另一个是匹配对象_sre.SRE_Match。其中匹配对象有几个常用的方法:

import re
result = re.search(r'(hi).(you)',r"this is a world,hi.you,can you see it?")
print(result.group(0))
print(result[0])
print(result.span(0))

print(result.group(1))
print(result[1])
print(result.span(1))

print(result.group(2))
print(result[2])
print(result.span(2))

print(result.groups())

# 可以为分组命名,这样groups就会有这些命名:
result2 = re.search(r'(?P<greet>hi).(?P<person>you)',r"this is a world,hi.you,can you see it?")
print(result2.groupdict())

# 返回传给search(),match()方法的pos参数。
print(result2.pos)
# 返回传给search(),match()方法的endpos参数。
print(result2.endpos)
# 匹配的分组个数。
print(result2.lastindex)
# 返回最后一个匹配的捕获组的名字,如果没有名字或没有组匹配,该属性返回None。
print(result2.lastgroup)
# 返回正则表达式匹配所用的正则表达式。
print(result2.re)
# 返回用于正则表达式的字符串。
print(result2.string)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

# 正则表达式标志位

前面提到的re.I表示使用正则表达式匹配时忽略大小写,除此之外还有很多像re.I的标志位:

标志位 含义 正则表达式
re.A 或 re.ASCII 控制\w,\W,\b,\B,\d,\D,\s,\S只匹配ASCII字符,不匹配所有Unicode字符 (?a)
re.DEBUG 显示编译正则表达式的Debug信息
re.I或re.IGNORECASE 使用正则表达式匹配时不区分大小写 (?i)
re.L或re.LOCALE 根据当前区域设置使用正则表达式时不区分大小写,只对bytes模式起作用 (?L)
re.M或re.MULTILINE 正则表达式"^"和"$"能跨越多行。默认只能匹配一行的开始和结尾 (?m)
re.S或re.DOTALL .能匹配包括换行符在内的所有字符,否则不包含换行符 (?s)
re.U或re.Unicode 控制\w,\W,\b,\B,\d,\D,\s,\S匹配所有Unicode字符,在Python3中多余
re.X或re.VERBOSE 允许为正则表达式书写注释,易于阅读 (?x)

# 创建正则表达式

正则表达式是代表一类字符串的模板,它可以匹配一批字符串,下面来看下创建这些模板的字符:

字符 解释
x x为任何合法字符
\uhhhh 十六进制0xhhhh所表示的Unicode字符
\t 制表符('\u0009')
\n 换行符('\u000A')
\r 回车符('\u000D')
\f 换页符('\u000C')
\a 报警符('\u0007')
\e Escape符('\u001B')
\cx x为对应控制符,比如\cC为Ctrl+C,x需要为大小写字母

正则表达式中的控制字符,如果要匹配下面这些字符,都需要使用\进行转义:

字符 解释
$ 匹配一行开头
^ 匹配一行结尾
() 子表达式(组)
[] 用于表示范围
{} 用于表示前面子表达式出现的频度
* 前面子表达式可以出现零次或多次
+ 前面子表达式可以出现一次或多次
? 前面子表达式可以出现零次或一次
. 匹配除换行符之外的任意字符
\ 转义下一个字符
| 两项中任选一项

正则表达式的通配符

字符 解释
. 默认匹配除换行符之外的任意字符
\d (digital)匹配0~9的所有数字
\D 匹配非数字
\s (space)匹配所有空白字符,包括空格,制表符,回车符,换页符,换行符
\S 匹配所有非空白字符
\w (word)匹配所有单词字符,包括0~9数字,26个英文字母和下划线(_)
\W 匹配所有非单词字符

上面的[]可以表示范围:

模式 例子 解释
枚举 [abc] 匹配a,b,c中的任意一个
范围 [a-d] 匹配a,b,c,d中的任意一个
求否范围 [^abc] 匹配非a,b,c中的其他字符

正则表达式支持的边界字符

字符 解释
$ 匹配一行开头
^ 匹配一行结尾
\b 只匹配单词前后的空白
\B 只匹配不在单词前后的空白
\A 只匹配字符串的开头
\Z 只匹配字符串的结尾

# 子表达式

子表达式可看作被匹配字符串的某一部分,能够作为组的概念来查看是否匹配。

import re
result = re.search(r'student (li|wang)[\w ]*,hi \1',"student li,hi li")
print(result)

# 匹配模式,但是并不捕获,不能用\1,\2来代表前面的捕获组,使用\1,\2会出现错误
result = re.search(r'student (?:li|wang)[\w ]*,hi ',"student li,hi li")
print(result)

result = re.search(r'<(?P<TagName>\w+)>\w*</(?P=TagName)>',"<h1>hello</h1>")
print(result)

# <h1>必须在左边,</h1>必须在右边
result = re.search(r'(?<=<h1>)\w*(?=</h1>)',"<h1>leftRight</h1>")
print(result)

# (?#注释)
result = re.search(r'(?<!</h1>)(?#左边不能出现)\w*(?!<h1>)',"<h1>leftRight2</h1>")
print(result)

# 整个正则表达式不区分大小写
result = re.search(r'(?i)[a-z0-9_]{2,}@qq\.com',"Xsmyqf@Qq.com")
print(result)

# 只有用户名不区分大小写
result = re.search(r'(?i:[a-z0-9_]){2,}@qq\.com',"Xsmyqf@qq.com")
print(result)

# 整个正则表达式不区分大小写,只有某个组区分大小写
result = re.search(r'(?-i:[a-z0-9_]){2,}@qq\.com',"xsmyqf@qQ.com",re.I)
print(result)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 贪婪模式与勉强模式

前面提到频数限定,也就是限定前面的字符串出现次数,现在再总结下:

模式 含义
{n,m} 出现n-m次
{n,} 出现至少n次
{,m} 出现最多m次
{n} 出现n次
* 等价{0,},出现0-N次
+ 等价{1,},出现1-N次
? 等价{0,1},出现0-1次

默认情况下,正则表达式匹配的频数是贪婪模式的,也就是尽可能多的匹配字符。但是在频数限定后面加一个问号,贪婪模式就会变成勉强模式,也就是尽可能少地匹配字符。

import re
result = re.search(r'(?i:[a-z0-9_]){2,}@.+\.',"xsmyqf@google.gmail.com")
print(result)

result = re.search(r'(?i:[a-z0-9_]){2,}@.+?\.',"xsmyqf@google.gmail.com")
print(result)
1
2
3
4
5
6

# 容器类

除了前面的list,tuple和dict等数据结构,Python还提供了set,deque,heap等数据结构。

# set

set集合的特点是:

  • 不能记录元素添加的顺序。
  • 元素不能重复。

来看下操作实例:

set1 = {'li'}
set1.add('wang')
set1.remove('wang')
set1.add('sun')

set2=set()
set2.add('li')

print("set1:%s" % set1)
print("set2:%s" % set2)

print("set1 is set2 super set:%s" % set2.issubset(set1))
print("set1 is set2 super set:%s" % (set2 <= set1))
print("set1 is set2 super set:%s" % set1.issuperset(set2))
print("set1 is set2 super set:%s" % (set1 >= set2))

print("see difference:%s" % (set1-set2))
print("see difference:%s" % set1.difference(set2))
#print(set1.difference_update(set2))

print("see difference:%s" % (set2-set1))
print("see difference:%s" % set2.difference(set1))

print("see intersection:%s" % (set1 & set2))
print("see intersection:%s" % set1.intersection(set2))
#print(set1.intersection_update(set2))

set3 = set(range(1,6))
set4 = set(range(4,9))
print("see union:%s" % set3.union(set4))
print("see union:%s" % (set3 | set4))

print("see xor:%s" % (set3 ^ set4))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

Python中的集合有固定集合,这种集合不能添加元素,但是可被添加到其他集合中:

fronzenset1 = frozenset('apple')
set1 = set('orange')
set2 = set("empty")
#set2.add(set1)
set2.add(fronzenset1)
print("set2:%s" % set2)

#fronzenset1.add("basketball")
#print("fronzenset1:%s" % fronzenset1)
set1.add("football")
print("set1:%s" % set1)
1
2
3
4
5
6
7
8
9
10
11

# deque

双端队列和队列,栈都点类似,它们的特点:

  • 队列:只允许数据从头进,从尾出。
  • 栈:只允许数据在从头进,从头出。
  • 双端队列:允许数据从头尾进,从头尾出。

Python中的deque每个方法都有两个版本,默认它是从右边添加元素,也就是默认右边是头,另一个版本是从左边添加元素,左边是尾。

from collections import deque
deque1 = deque('123')
deque1.append('4')
deque1.appendleft('5')
print(deque1)
# 默认是从头(右端)存,从头取。
print(deque1.pop())
print(deque1.popleft())
print(deque1)

# 首尾错位
deque1.rotate()
print(deque1)
1
2
3
4
5
6
7
8
9
10
11
12
13

# heap

堆分为小顶堆和大顶堆,小顶堆的特征是第n个元素小于等于第2n+1和2n+2个元素,大顶堆的特征是第n个元素大于等于第2n+1和2n+2个元素。Python没有直接提供堆这种数据结构,它直接把列表当成堆来处理,这些操作是基于小顶堆的。

from heapq import *
heaplist=[1,4,2,7,3,9,10,5]
heapify(heaplist)
print("apply heap oper:%s" % heaplist)
heappush(heaplist,8)
print("add element 8:%s" % heaplist)
print("get element : %s" % heappop(heaplist))
print("after oper:%s" % heaplist)
print("pop lowest element %s and replaced with appointed element:%s" % (heapreplace(heaplist,12),heaplist))
print("最大的3个元素 :%s" % nlargest(3,heaplist))
print("最小的4个元素 :%s" % nsmallest(4,heaplist))
1
2
3
4
5
6
7
8
9
10
11

# ChainMap

ChainMap可以将多个dict链接到一块,作为一个整体被处理。

from collections import ChainMap

dict1={'name':'li'}
dict2={'age':30}
dict3={'course':'chinese'}

personInfo=ChainMap(dict1,dict2,dict3)
print(personInfo)

dict2['age']=27
print(personInfo)
1
2
3
4
5
6
7
8
9
10
11

可以通过ChainMap来把局部范围,全局范围,Python内置定义范围做成一个字典,依次查找定义。

from collections import ChainMap
import builtins
name = "xie"
def funcScope():
    #name="li"
    innerDict=ChainMap(locals(),globals(),vars(builtins))
    print(innerDict["name"])

funcScope()
1
2
3
4
5
6
7
8
9

同理应用到程序接收运行时参数:

from collections import ChainMap
import os,argparse

defaultParams={'user':'admin','privilege':'customer'}

runtimeParser = argparse.ArgumentParser()
runtimeParser.add_argument('-u','--user')
runtimeParser.add_argument('-p','--privilege')

runtimeParameter = runtimeParser.parse_args()

# 去掉无用参数

MyRuntimeParameter = {k:v for k,v in vars(runtimeParameter).items() if v}

parameterResult = ChainMap(MyRuntimeParameter,os.environ,defaultParams)

print(parameterResult["user"])
print(parameterResult["Java_Home"])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# Counter

Counter类继承了dict类,还提供了三个方法:

from collections import Counter
c1 = Counter("hello,world")
print(c1)

for one in c1.elements():
    print(one)

print(c1.most_common(3))

c2 = {'l':1}
c1.subtract(c2)
print(c1)

print(sum(c1.values()))
print(list(c1))
print(set(c1))
print(dict(c1))

print(c1.items())

c3 = Counter('abbcccdddde')
c4 = Counter('aabcddd')

print("c3:%s" % c3)
print("c4:%s" % c4)

print("c3 - c4 : %s" % (c3-c4))
print("c3 + c4 : %s" % (c3+c4))
print("c3 & c4 : %s" % (c3 & c4))
print("c3 | c4 : %s" % (c3 | c4))

c5 = Counter({"a":-3,"b":2})
print(-c5)
print(+c5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# defaultdict

defaultdict是dict子类,但是它与dict区别在于,当试图访问不存在的键时,它会提供一个default_factory属性,而不是只抛出KeyError异常。

from collections import defaultdict

dict1 = defaultdict(str)
print(dict1["test"])

sourceDict = [("apple","red"),("banana","yellow"),("apple","ball"),("apple","sweet"),("banana","square")]

orgDict = {}
defaultDict = defaultdict(list)

for k,v in sourceDict:
    orgDict.setdefault(k,[]).append(v)
    defaultDict[k].append(v)

print(orgDict)
print(list(defaultDict.items()))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# nametuple

它是一个工厂函数,可以创建tuple类的子类,它与其他tuple不同的是,该子类可以为tuple的每个元素都指定字段名,这样可以根据字段名来访问nametuple的各元素。

from collections import namedtuple
Position = namedtuple('Pos',['y','x'])
p1 = Position(1,2)

print(Position)
print(p1[0],p1[1])
print(p1.x,p1.y)

p2 = Position._make([4,3])
# 转换为OrderedDict,根据放入元素的先后顺序排序
print(p2._asdict())
print(p2._replace(y=10))
print(p2)
print(p2._fields)

Color = namedtuple("Color","red green blue")
Pixel = namedtuple("Pixel",Position._fields+Color._fields)
pix1 = Pixel(1,2,220,210,200)
print(pix1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# OrderedDict

它是dict子类,它与普通dict的区别是它会按添加键值对的顺序来存储数据。先添加的排在前面,后添加的排在后面,当两个OrderedDict元素相同顺序不同时,也会被判断为不相等。

from collections import OrderedDict

orderDict1 = OrderedDict(b=10,c=3,a=8)
print(orderDict1)

orderDict1.move_to_end('b')
print(orderDict1)

orderDict1.move_to_end('b',last=False)
print(orderDict1)

print("keys : %s" % orderDict1.keys)

print("pop last added element:%s" % orderDict1.popitem()[0])

print("pop earliest added element:%s" % orderDict1.popitem(last=False)[0])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 函数类

# itertools

这个模块包含了一些用于生成迭代器的函数:

import itertools as it

# 生成等差数列

for e in it.count(3,2):
    print(e,end=", ")
    if e > 10 :
        break
print()

# 循环序列
counter=0
for e in it.cycle(["apple","banana","android"]):
    print(e,end=", ")
    counter+=1
    if counter >10:
        break
print()

# 重复序列
for e in it.repeat('Hello',3):
    print(e,end=", ")
print()

# 累加
for e in it.accumulate(range(6)):
    print(e,end=', ')

print()

# 自定义累加
for e in it.accumulate(range(6),lambda x,y: x+y+1):
    print(e,end=', ')
print()

# 将几个数组合并
for e in it.chain(['a','b','c'],[1,2,3,4]):
    print(e,end=', ')
print()

# 按照权重压缩值
for e in it.compress(["a","b","c"],[0,1,2]):
    print(e,end=', ')
print()

# 使用一个条件对序列的每个元素依次判定,获取从开始为False的元素到末尾的元素。
for e in it.dropwhile(lambda x: x<10,[1,4,12,6,7]):
    print(e,end=', ')
print()

# 使用一个条件对序列的每个元素依次判定,获取从开始的元素到开始为False的之前元素。
for e in it.takewhile(lambda x: x < 10,[1,4,12,6,7]):
    print(e,end=', ')
print()

# 使用一个条件对序列的每个元素依次判定,获取返回为False的元素。
for e in it.filterfalse(lambda x: x < 10,[1,4,12,6,7]):
    print(e,end=', ')
print()

# 使用一个函数来操作序列中的元组,并返回一个由运算结果组成的列表
for e in it.starmap(pow,[(2,3),(4,3)]):
    print(e,end=', ')
print()

# 将两个列表中的每个元素合并到一个新的列表中。
for e in it.zip_longest("abcd","12",fillvalue="-"):
    print(e,end=', ')
print()

# 排列组合
for e in it.product("AB","CD"):
    print(e,end=', ')
print()

# 排列组合
for e in it.product("AB",repeat=2):
    print(e,end=', ')
print()

# 排列组合,所包含元素能重复,但是组合过程元素不可以重复
for e in it.permutations("ABC",2):
    print(e,end=', ')
print()

# 排列组合,所包含元素不能重复,但是组合过程元素不可以重复
for e in it.combinations("ABC",2):
    print(e,end=', ')
print()

# 排列组合,所包含元素不能重复,但是组合过程元素可以重复
for e in it.combinations_with_replacement("ABC",2):
    print(e,end=', ')
print()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

# functools

该模块中包含一些函数装饰器以及一些工具函数。

from functools import *
#from time import *
import time
from decimal import *

# 将计算出来的函数结果作为下一次计算的初始值。
def addFunc(x,y):
    print(x,y)
    return x+y

print(reduce(addFunc,range(5)))
print(reduce(addFunc,range(5),4))


# Python3不支持老式比较函数,需要转换为关键字函数
def cmp_old(o1,o2):
    return o2-o1
cmplist = [1,4,2,9,7,5,2]
cmplist.sort(key=cmp_to_key(cmp_old))
print("after sorted:%s" % cmplist)

# 使用LRU缓存算法来缓存相对耗时的函数结果
@lru_cache(maxsize=32)
def getTotalSum(n):
    if n == 1 :
        return 1
    else:
        return n+getTotalSum(n-1)

t1=time.time()
print(getTotalSum(90))
t2=time.time()
print(t2-t1)

# 为函数部分参数指定参数值,得到一个转换后的函数。
baseTwo = partial(int,base=2)
baseTwo.__doc__="将二进制形式的字符串转换为整数"

print(baseTwo("1101"))
print(int("1101",2))

# 为类中方法的部分参数绑定值。
class Person:
    def __init__(self):
        self.IsStudent=True
    def SetIsStudent(self,status):
        self.IsStudent=status
    set_is_student=partialmethod(SetIsStudent,True)
    set_not_is_student=partialmethod(SetIsStudent,False)

p1=Person()
p1.set_is_student()
print(p1.IsStudent)
p1.set_not_is_student()
print(p1.IsStudent)

# 自动为类生成比较方法
@total_ordering
class Student:
    def __lt__(self,other):
        print("__lt__ method!")

print("gt method:%s" % Student.__gt__)

# 函数重载
@singledispatch
def testOverWrite(v1,v2):
    print("normal value:%s" % v1)

@testOverWrite.register(int)
def _(v1,v2):
    print("int value:%s" % v1)

def NoneFunc(v1,v2):
    print("none func:%s" % v1)

testOverWrite.register(type(None),NoneFunc)

@testOverWrite.register(float)
@testOverWrite.register(Decimal)
def testFunc(v1,v2):
    print("decimal function!")

testOverWrite('hello',0)
testOverWrite(1,0)
testOverWrite(None,0)
testOverWrite(12.2,0)

print(testFunc is testOverWrite.dispatch(float))
print(testFunc is testOverWrite)

# 查看重载的所有类型
print(testOverWrite.registry.keys())
# 查看某类型的重载函数
print(testOverWrite.registry[int])

# 包装函数

def decorator(f):
    """包装函数"""
    @wraps(f)
    def tw(*arg,**dictargs):
        """包装函数里的装饰函数"""
        print("现在在装饰函数里面!")
        return f(*arg,**dictargs)
    return tw

@decorator
def test():
    """测试函数"""
    print("执行测试函数")

def decorator2(f):
    """包装函数2"""
    def tw(*arg,**dictargs):
        """包装函数里的装饰函数2"""
        print("现在在装饰函数里面2!")
        return f(*arg,**dictargs)
    return update_wrapper(tw,f)

@decorator2
def test2():
    """测试函数2"""
    print("执行测试函数2")



test()
print("function name : %s" % test.__name__)
print("function doc : %s" % test.__doc__)

test2()
print("function name : %s" % test2.__name__)
print("function doc : %s" % test2.__doc__)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134