参考引用于《Effective Python》 Brett Slatkin
function-函数
14、返回值
- 不返回None
- 尽量raise 异常
15、闭包中使用外围作用域的变量
闭包:一中定义在某个作用域的函数,这个函数引用了那个作用于里面的变量,helper是闭包
defsort_x(values, group): found=Falsedefhelper(x): ifxingroup: found=Truereturn (0, x) return (1,x) values.sort(key=helper)
- 闭包中可以调用外围的变量,但是闭包中对外围变量进行赋值,不会污染外围变量。即使经过了调用,found的值也不会发生改变–>使用nonlocal
defsort_x(values, group): found=Falsedefhelper(x): nonlocalfound#闭包中的改变,也会影响外围变量ifxingroup: found=Truereturn (0, x) return (1,x) values.sort(key=helper)
与global形成一种互补(类似),global作用域模块的全局。nonlocal不会作用域模块间
- python2 无法使用
16、生成器直接改写 返回列表的函数
- 优点:
- 更清晰
- 可以传给yield,以此产生出来
- 不会影响执行时所耗费内存
- 常规写法:
/
defindex_words(text): result= [] iftext: result.append(0) forindex, letterinenumerate(text): ifletter==' ': result.append(index+1) returnresult### exp:[0, 7, 13, 17, 27]x=index_words2('asdasd asdas asd asdasdasd asdas') print(x)
- 改进一:生成器函数
defindex_words2(text): iftext: yield0forindex, letterinenumerate(text): ifletter==' ': yieldindex+1### exp:[0, 7, 13, 17, 27]x=index_words2('asdasd asdas asd asdasdasd asdas') print(list(x))
- 缺点:输入量过大,list崩溃
- 改进二:生成器改写,解数据量大
defindex_words3(text): offset=0forlineintext: # 最大消耗内存为单行最长的字符数,进行了内存的清空操作ifline: yieldoffsetforindex, letterinenumerate(line): offset+=1ifletter==' ': yieldoffsetif__name__=="__main__": withopen('1.txt', 'r') asr: rr=index_words3(r) result=itertools.islice(rr, 0, 3) #直接对迭代器的内容进行操作print(list(result))
17. 迭代器注意事项(再学习)
- 以迭代器为参数,可能无法返回任何现象
- 因为:在抛出Stop Iteration异常(例如for循环的结束)后的迭代器和生成器上继续迭代,不会产生结果
- 同时拥有
__iter__
和__next__
构成可迭代对象,容器应该 - https://www.zlovezl.cn/articles/mastering-container-types/ (关于容器的博文,学习)
classtext: def__init__(self): self.path=''# 修改这个东西,可以改变当前容器的类型 def__iter__(self): withopen('data/number.txt', 'r') asr: forvinr: print(v)
- 核心是减少内存的高频交换,多使用iter进行处理
18. 数量可变的位置参数减少视觉杂乱
- 优势:之前必须传入很多参数,导致程序写法固定,即使不需要也得进行输入
- 缺点:
- *的操作符为生成器的参数,必须先迭代一遍。每一个值都放入tuple(变长需要先转化为元组)。迭代的还是别用
\*args
了 - 错误的传入被屏蔽了,程序不报错
19. 用关键字参数表达参数输入
- 如题 √
20. None & 文档字符串描述具有动态默认值的参数
importdatetimefromtimeimportsleepdeflog(message, when=datetime.datetime.now()): print(when,message) if__name__=='__main__': log('first') sleep(1) log('second') #### 2020-09-22 16:46:16.833298 first#### 2020-09-22 16:46:16.833298 second'问题:竟然两次输出的时间一致--》函数只在初始化的时候加载了一次,datetime.now()只进行了一次'## 只要不在函数传值是抛出这些就OK
- 即使传递的时候定义为
{} []
这些也不行,在初次运行时也会进行定义。一定要定义为None
21.关键词形式制定的参数保证明晰
- 如题