第十九章 函数的高级话题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十九章 函数的高级话题相关的知识,希望对你有一定的参考价值。
‘‘‘ void Fun0(CRITICAL_SECTION* p) { LeaveCriticalSection(p); } auto Fun1 = [](CRITICAL_SECTION* p){LeaveCriticalSection(p);}; CRITICAL_SECTION Cs; shared_ptr<CRITICAL_SECTION> pShareCs(&Cs, [](CRITICAL_SECTION* p){LeaveCriticalSection(p);}); unique_ptr<CRITICAL_SECTION, decltype(Fun0)*> pUniqueCs0(&Cs, Fun0); unique_ptr<CRITICAL_SECTION, decltype(Fun1)> pUniqueCs1(&Cs, Fun1); //unique_ptr<CRITICAL_SECTION, decltype([](CRITICAL_SECTION* p){LeaveCriticalSection(p);})> pUniqueCs2(&Cs, [](CRITICAL_SECTION* p){LeaveCriticalSection(p);}); //error C3477: lambda 不能出现在未计算的上下文中 //unique_ptr<CRITICAL_SECTION> pUniqueCs3(&Cs, Fun1); //error C2664: “std::unique_ptr<_Ty>::unique_ptr(_RTL_CRITICAL_SECTION *,const std::default_delete<_Ty> &)”: 不能将参数 2 从“`anonymous-namespace‘::<lambda0>”转换为“const std::default_delete<_Ty> &” ‘‘‘ #1. #A:设计函数的时候,最好考虑下代码的重用性 #B:一般需让函数独立于外部的东西,少用全局变量,因为后者容易引发依赖关系,导致程序调试和修改的困难 #C:不要改变可变类型参数,除非调用者希望这样做 #D:每一个函数都应该有一个单一的、统一的目标,否则是无法重用在一个函数中把所有步骤都混合在一起的代码的 #E:每一个函数应该相对较小,一个过长或者有着过深嵌套的函数往往就成为设计权限的征兆,保持简单,保持剪短 #F:通常来讲,我们应该竭力使函数和其他编程组件中的外部依赖性最小化。函数的自包含性越好,它越容易被理解、复用和修改 #2. #A:向函数添加任意属性 def fun():pass value = dir(fun) #value = [‘__annotations__‘, ‘__call__‘, ‘__class__‘, ‘__closure__‘, ‘__code__‘, ‘__defaults__‘, ‘__delattr__‘, ‘__dict__‘, ‘__dir__‘, ‘__doc__‘, ‘__eq__‘, ‘__format__‘, ‘__ge__‘, ‘__get__‘, ...] nLen = len(value) #nLen = 34 fun.count = 0 nLen = len(dir(fun)) #nLen = 35 funCopy = fun value = funCopy.count #value = 0 #3. #A:可以给函数附加注解信息,是与函数的参数合结果相关的任意的用户定义的数据,注解是可选的,并且出现的时候只是附加到函数对象的__annotations__属性以供使用 (annotations 即注释) #B:如果对参数使用默认值--注解(及其:字符)出现在默认值(及其=字符)之前 #C:注解只对def语句有效,在lambda中无效 def fun(a = 10, b = 20): return a,b dir0 = fun.__annotations__ #dir0 = {} def fun(a : int, b : ‘B‘, c : list = [1, 2]) : pass dir1 = fun.__annotations__ #dir1 = {‘a‘: <class ‘int‘>, ‘b‘: ‘B‘, ‘c‘: <type>} def fun(a : int, b : ‘B‘, c : list = [1, 2])-> tuple : return a, b, c value = fun(1, 2) #value = (1, 2, [1, 2]) dir2 = fun.__annotations__ #dir2 = {‘a‘: <class ‘int‘>, ‘b‘: ‘B‘, ‘c‘: <type>, ‘return‘: <type>} #4. #A:就像def一样,lambda表达式创建了一个之后能调用的函数,但是它返回一个函数而不是将这个函数赋值给一个变量名 #B:lambda是一个表达式而不是一个语句,所以lambda能出现在Python不允许def出现的地方 #C:lambda的主体是一个单个的表达式而不是一个代码块,只能封装有限的逻辑 #D:在lambda主体中的代码像在def内的代码一样都遵守相同的作用域查找规则 lam0 = lambda x, y, z : x + y + z value = lam0(1, 2, 3) #value = 6 lam1 = lambda x, y, z : (y + z if x else y - z) value = lam1(0, 1, 2) #value = -1 value = lam1(1, 1, 2) #value = 3 L0 = [1, 2] lam2 = lambda : [x ** 2 for x in L0] value = lam2() #value = [1, 4] #lam3 = lambda x : if x: print(x) #无法通过编译 #5. import sys from tkinter import Button, mainloop x = Button( text = "press me", command = (lambda : print(‘Hello World‘))) x.pack() mainloop() #上面这段代码将会创建一个界面,界面上有一个按钮名字为 press me 每次点击都会在控制台输出 Hello World #6. #A:map函数会对一个序列对象中的每一个元素应用被传入的函数,返回一个可迭代的对象,包含所有序列元素应用函数调用后的结果 #B:对于多个序列,map期待一个N参数的函数用于N序列 #C:filter根据传入值是否为真来进行筛选,返回为真的值 #D:reduce可以按照给定的方法把输入参数中的序列缩减为单个值,提供第三个参数,当传入序列为空时候的一个默认结果 L0 = [1, 2, 3] L1 = list(map(lambda x : x + 10, L0)) #L1 = [11, 12, 13] L2 = list(map(lambda x, y : x + y, L0, L1)) #L2 = [12, 14, 16] L3 = list(filter(lambda x : x > 0, range(-5, 5))) #L3 = [1, 2, 3, 4] from functools import reduce list0 = [1, 2, 3, 4] value = reduce(lambda x, y : x + y, list0) #value = 10 value = reduce(lambda x, y : x * y, list0) #value = 24 try: value = reduce(lambda x, y : x * y, []) except: pass #运行至此 value = reduce(lambda x, y : x * y, [], ‘a‘) #value = ‘a‘
以上是关于第十九章 函数的高级话题的主要内容,如果未能解决你的问题,请参考以下文章