try except else
else段的作用主要是减少try代码块中的代码量,使结构更清晰
if __name__ == '__main__':
try:
1/2 # exception
except Exception as e:
raise e
else:
print('when no exception, exec this code')
generator
通过()产生generator
res:<generator object at 0x00000221045807C8>
if __name__ == '__main__':
l = [1,2,3,4]
g = (x + 1 for x in l)
print(g)
元组的sort
对元组的排序是根据下标索引从0开始的
作用域
def helper(numbs, be_founds):
found = False
def find():
for x in be_founds:
if x in numbs:
found = True
find()
return found # found一定是False
if __name__ == '__main__':
l = [1,2,3,4,5,6]
k = [2,4,5]
print(helper(l, k))
引用变量时按照以下顺序遍历作用域:
1.当前函数作用域
2.任意外围作用域(包含当前函数的其他函数)
3.包含当前代码模块的作用域(全局作用域global)
4.内置作用域(包含len str等函数的作用域)
给变量赋值时不同,如果当前作用域有该变量,那么给该变量赋新值;没有该变量的话python会把这次赋值认为是定义新变量。
当把变量声明为nonlocal,那么值就会被改变(不建议这么做,因为可能会出现其奇奇怪怪的BUG)
def helper(numbs, be_founds):
found = False
def find():
nonlocal found
for x in be_founds:
if x in numbs:
found = True
find()
return found # found的值会被改变
if __name__ == '__main__':
l = [1,2,3,4,5,6]
k = [2,4,5]
print(helper(l, k))
当一个变量是mutable的时候(比如list、dict、set、类的某个对象),即使不在当前作用域也可以修改:
def helper(numbs, be_founds):
found = [False]
def find():
for x in be_founds:
if x in numbs:
found[0] = True
find()
return found[0] # found的值会被改变
if __name__ == '__main__':
l = [1,2,3,4,5,6]
k = [2,4,5]
print(helper(l, k))
对容器的遍历
对容器x的遍历实际上是调用了iter(x)函数,然后调用了x. _ _iter _ _()方法,该方法需要返回generator对象。遍历的时候会不停的使用next(generator),直到没有值为止。
class Mycont():
def __init__(self):
self.vals = [1,2,3,4]
def __iter__(self):
for x in self.vals:
yield x
if __name__ == '__main__':
print(sum(Mycont()))
解包
如果要把列表作为位置参数传递的话,需要在前边加*,字典对象作为关键字参数传递的话需要加 * *
位置参数必须在关键字参数之前
def f(val, *args, **kwargs):
print(val)
print(args)
print(kwargs)
if __name__ == '__main__':
val = 'xxxx'
l = [1,2,3,4]
d = {'x': 1, 'y': 2}
f(val, *l, **d)
参数的默认值问题
import time
from datetime import datetime
def log(msg, t=datetime.now()):
print('%s: %s' % (msg, t))
if __name__ == '__main__':
log('hi')
time.sleep(1)
log('hi')
# res:
# hi: 2019-12-18 10:30:09.754222
# hi: 2019-12-18 10:30:09.754222
# 两次的时间是一样的,因为该默认参数是不可变数据类型,在函数加载的时候就已经定义了,不会改变
# 参数的默认值只会在程序加载到该函数的时候评估一次。
import json
def decode(data, default={}):
try:
return json.loads(data)
except Exception as e:
return default
if __name__ == '__main__':
x = decode('adfagag')
x['t1'] = '1'
y = decode('asdfg')
y['t2'] = '2'
z = decode('sdagg', default={'corr': 'c1'})
print(x)
print(y)
print(z)
# res:
# {'t1': '1', 't2': '2'}
# {'t1': '1', 't2': '2'}
# {'corr': 'c1'}
# 可以看出z的结果才是我们想要的。
# 参数在加载该函数的时候已经赋值,由于是可变参数,值可以改变,任何以默认参数形式调用该函数的情况下共享同一个default对象
# 导致x和y的值一样
# 可变类型的参数默认值尽量默认为None
assert x is y
只能通过关键字参数传递的方式
# 加了*表示 *之后的参数只能通过关键字参数来指定,不能通过位置参数
def decode(c1, *, c2='c2', c3='c3'):
print(c1, c2, c3)
if __name__ == '__main__':
decode('111', c2='sdf', c3='sdf') # corr
decode('111', '222') # error