标准库
datetime模块
对日期、时间、时间戳的处理
-
datetime类
-
类方法:
today():返回本地时区当前时间的datetime对象
now(tz=None):返回当前时间的datetime对象,时间到微秒,如果tz为None,返回和today()一样
utcnow():没有时区的当前时间(国际化的时候建议用这个)
fromtimestamp(timestamp , tz = None) 从一个时间戳返回一个datetime对象
-
datetime对象
- timestamp():返回一个到微秒的时间戳
- 时间戳:格林威治时间1970年1月1日0点到现在的秒数。
- 构造方法 datetime.datetime(2016, 12, 6, 16, 29, 43, 79043)
- year、month、day、hour、minute、second、microsecond,取datetime对象的年月日时分秒及微秒
- weekday() 返回星期的天,周一0,周日6
- isoweekday() 返回星期的天,周一1,周日7
- date() 返回日期date对象
- time() 返回时间time对象
- replace() 修改并返回新的时间
- isocalendar() 返回一个三元组(年,周数,周的天)
- timestamp():返回一个到微秒的时间戳
-
日期格式化
类方法 strptime(date_string, format) ,返回datetime对象
对象方法 strftime(format) ,返回字符串
-
字符串format函数格式化
import datetime dt = datetime.datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M") print(dt.strftime("%Y-%m-%d %H:%M:%S")) print("{0:%Y}/{0:%m}/{0:%d} {0:%H}::{0:%M}::{0:%S}".format(dt))
-
-
timedelta对象
datetime2 = datetime1 + timedelta
datetime2 = datetime1 - timedelta
timedelta = datetime1 - datetime2
-
构造方法
- datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0) - year = datetime.timedelta(days=365)
total_seconds() 返回时间差的总秒数
time模块
- time.sleep(secs) 将调用线程挂起指定的秒数(发起一个系统调用,让程序暂停)
解析式
列表解析式
- 语法:
[返回值 for 元素 in 可迭代对象 if 条件]
使用中括号[],内部是for循环,if条件语句可选
返回一个新的列表
- 列表解析式是一种语法糖:
- 编译器会优化,不会因为简写而影响效率,反而会因优化而提高了效率。
- 减少了程序员工作量,减少出错。
- 简化了代码,但可读性增强,不便于可读。
- 举例:
- 获取10以内的偶数
#普通
even = []
for x in range(10):
if x % 2 == 0:
even.append(x)
#解析式
even = [x for x in range(10) if x%2 == 0]
- 思考:
有这样的赋值语句
newlist = [print(i) for i in range(10)]
打印出来的是什么?
print()把所有的i全打印出来,newlist里面则是10个None获取20以内的偶数,如果同时是3的倍数,把它打印出来
[i for i in range(20) if not i % 2 and i % 3 == 0]
[i for i in range(20) if not i % 2 if i % 3 == 0]
获取20以内2的倍数或者3的倍数,把它打印出来
[i for i in range(20) if not i % 2 or i % 3 == 0]
"0001.abadicddws" 是ID格式,要求ID格式是以点号分割,左边是4位从1开始的整数,右边是
10位随机小写英文字母。请依次生成前100个ID的列表
import string
import random
x= string.ascii_lowercase
["{:>04}.{}".format(i,"".join(random.choices(x,k = 10))) for i in range(1,8)]
['0001.rvverptnre',
'0002.beqkpbxhfl',
'0003.woxvvayzjo',
'0004.wrbnnkelcc',
'0005.kpsjowcfvz',
'0006.pnqwqzlttc',
'0007.wehobydqnf']
字典解析式
- 语法:
- {返回值 for 元素 in 可迭代对象 if 条件}
- 列表解析式的中括号换成大括号{}就行了
- 使用key:value形式
- 立即返回一个字典
用法:
{x:(x,x+1) for x in range(10)}
{x:[x,x+1] for x in range(10)}
{(x,):[x,x+1] for x in range(10)}
{[x]:[x,x+1] for x in range(10)} #[x]不可哈希,字典的k要求可哈希
{chr(0x41+x):x**2 for x in range(10)}
{str(x):y for x in range(3) for y in range(4)} # 输出多少个元素?
#会覆盖,返回{0:3,1:3,2:3}
集合解析式
- 语法
- {返回值 for 元素 in 可迭代对象 if 条件}
- 列表解析式的中括号换成大括号{}就行了
- 立即返回一个集合
用法
{(x,x+1) for x in range(10)}
{[x] for x in range(10)} #[x]是个集合,不能哈希,所以放在集合解析式里面会报错
生成器
生成器Generator
生成器指的是生成器对象,可以由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,调用这个函数得到一个生成器对象。
生成器函数:
-
函数体内包含yield语句的函数,返回一个生成器对象,生成器函数的函数体不会立即执行。
生成器对象,是一个可迭代对象,是一个迭代器。
生成器对象,是延迟计算,惰性求值。
next(generator)会从函数的当前位置向后执行到之后碰到的第一个yield语句,会弹出值,并暂停函数执行。
再次执行会执行到下一个yield语句,没有多余的yield语句能执行,如果函数没有显式的return语句,继续调用next函数就会抛出StopIteration异常。
return会导致无法继续获取下一个值,抛出StopIteration异常。
-
生成器函数,它是函数,不过这个函数不像普通的函数调用时能返回一个合法的值,它返回的是一个还没有求过任何值的生成器对象,用next拨一下才会往后执行一下。
#举例 def gen(): print('line 1') yield 1 print('line 2') yield 2 print('line 3') return 3 next(gen()) # line 1 next(gen()) # line 1 g = gen() print(next(g)) # line 1 print(next(g)) # line 2 print(next(g, 'End')) # 没有元素给个缺省值 print(next(g, 'End')) # 没有元素给个缺省值
生成器的应用
#计数器
def inc():
def counter():
i = 0
while True:
i += 1
yield i
c = counter()
return lambda : next(c)
foo = inc()
print(foo()) #调用的时候是因为inc()函数返回的是一个匿名函数,而匿名函数的调用方式是(lambda 参数列表:函数体)(),所以调用的时候是foo后要加上(),即也就是inc()()。
#等价于
def inc():
def counter():
i = 0
while True:
i += 1
yield i
c = counter()
def _inc(): #用到外面的自由变量(c):闭包
return next(c)
return _inc
foo = inc() #可调用对象,函数
print(foo())
yield from
yield from是python3.3出现的新语法
yield from iterable 是for item in iterable: yield item形式的语法糖。
for x in range(1000):
yield x
#等价于
yield from range(1000)
从可迭代对象中一个个拿数据
def counter(n): #生成器,迭代器
for x in range(n):
yield x
def inc(n):
yield from counter(n)
foo = inc(10)
print(next(foo))
print(next(foo))
协程coroutine
生成器的高级用法
比进程、线程轻量级
是在用户空间调度函数的一种实现
Python3 asyncio就是协程实现,已经加入到标准库
Python3.5 使用async、await关键字直接原生支持协程
协程调度器实现思路
- 有2个生成器A、B
- next(A)后,A执行到了yield语句暂停,然后去执行next(B),B执行到yield语句也暂停,然后再次调用next(A),再调用next(B)在,周而复始,就实现了调度的效果
- 可以引入调度的策略来实现切换的方式
协程是一种非抢占式调度
生成器表达式Generator expression
- 语法
(返回值 for 元素 in 可迭代对象 if 条件)
列表解析式的中括号换成小括号就行了
返回一个生成器
- 和列表解析式的区别
生成器表达式是按需计算(或称惰性求值、延迟计算),需要的时候才计算值,返回迭代器,可以迭代,从前到后走完一遍后,不能回头。
列表解析式是立即返回值,返回的不是迭代器,返回可迭代对象列表, 从前到后走完一遍后,可以重新回头迭代。
- 和列表解析式的对比
- 计算方式
- 生成器表达式延迟计算,列表解析式立即计算
- 内存占用
- 单从返回值本身来说,生成器表达式省内存,列表解析式返回新的列表
- 生成器没有数据,内存占用极少,但是使用的时候,虽然一个个返回数据,但是合起来占用的内存也差不多
- 列表解析式构造新的列表需要占用内存
- 计算速度
- 单看计算时间看,生成器表达式耗时非常短,列表解析式耗时长
- 但是生成器本身并没有返回任何值,只返回了一个生成器对象
- 列表解析式构造并返回了一个新的列表
- 生成器
- 可迭代对象(able结尾)
- 迭代器(or结尾),是不是迭代器用next()方法可以检测,iter()方法可以把一个可迭代对象封装成迭代器。
- 生成器和迭代器是不同的对象,但都是可迭代对象,生成器对象,就是迭代器对象,迭代器不一定是生成器。
内建函数
- 标识 id
- 返回对象的唯一标识,CPython返回内存地址
- 哈希 hash()
- 返回一个对象的哈希值
- 类型 type()
- 返回对象的类型
- 类型转换
- float() int() bin() hex() oct() bool() list() tuple() dict() set() complex() bytes() bytearray()
- 输入 input([prompt])
- 接收用户输入,返回一个字符串
- 打印 print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
- 打印输出,默认使用空格分割、换行结尾,输出到控制台
- 对象长度 len(s)
- 返回一个集合类型的元素个数
- isinstance(obj, class_or_tuple)
- 判断对象obj是否属于某种类型或者元组中列出的某个类型
- isinstance(True, int)
- issubclass(cls, class_or_tuple)
- 判断类型cls是否是某种类型的子类或元组中列出的某个类型的子类
- issubclass(bool, int)
绝对值abs(x) x为数值
最大值max() 最小值min()
- 返回可迭代对象中最大或最小值
- 返回多个参数中最大或最小值
round(x) 四舍六入五取偶,round(-0.5)
pow(x , y) 等价于 x**y
range(stop) 从0开始到stop-1的可迭代对象;range(start, stop[, step])从start开始到stop-1结束步长为step的可迭代对象
divmod(x, y) 等价于 tuple (x//y, x%y)
sum(iterable[, start]) 对可迭代对象的所有数值元素求和,start:初始值
- sum(range(1,100,2))
- chr(i) 给一个一定范围的整数返回对应的字符
- chr(97) chr(20013)
- ord(c) 返回字符对应的整数
- ord('a') ord('中')
- sorted
sorted(iterable[, key][, reverse] )排序
- 返回一个新的列表,默认升序
- reverse是反转
sorted([1, 3, 5])
sorted([1, 3, 5], reverse=True)
sorted({'c':1, 'b':2, 'a':1})
- 翻转 reversed(seq)
返回一个翻转元素的迭代器(惰性求值)
list(reversed("13579"))
{ reversed((2, 4)) } # 有几个元素?
for x in reversed(['c','b','a']):
print(x)
reversed(sorted({1, 5, 9}))
- 枚举 enumerate(seq, start=0)
迭代一个序列,返回索引数字和元素构成的二元组
start表示索引开始的数字,默认是0
for x in enumerate([2,4,6,8]):
print(x)
for x in enumerate("abcde"):
print(x,end=" ")
- 迭代器和取元素 iter(iterable)、next(iterator[, default])
iter将一个可迭代对象封装成一个迭代器
next对一个迭代器取下一个元素。如果全部元素都取过了,再次next会抛StopIteration异常
it = iter(range(5))
next(it)
it = reversed([1,3,5])
next(it)
- 拉链函数zip(*iterables)
像拉链一样,把多个可迭代对象合并在一起,返回一个迭代器
将每次从不同对象中取到的元素合并成一个元组
list(zip(range(10),range(10)))
list(zip(range(10),range(10),range(5),range(10)))
dict(zip(range(10),range(10)))
{str(x):y for x,y in zip(range(10),range(10))}