python学习手册19 函数的高级话题
结果
点击(此处)折叠或打开
- #!/usr/bin/env python
- #-*- coding:utf8-*-
- '''
- 函数设计概念
- 有针对性的函数-聚合性
- 函数如何通信-耦合性
- 耦合性:对于输入使用参数并且对于输出使用return语句。
- 耦合性:只有真正必要的情况下使用全局变量。
- 耦合性:不要改变可变类型的参数,除非调用者希望这样做。
- 聚合性:每个函数都应该有一个单一的、统一的目标。
- 大小:每个函数都应该相对较小。
- 耦合:避免直接改变在另一个模块文件中的变量。
- 递归函数
- 直接或间接地调用自身以进行循环的函数。
- 它在python中相对少见,它是一项应该了解的有用技术,因为它允许遍历拥有任意的,不可预知的形状的结构。
- 函数对象:属性和注解
- 函数全部存储在内存中,可以跨程序自由地传递和间接调用。也支持与调用无关的操作--属性存储和注解。
- 函数可以由一个函数表达式后面的括号中的列表参数调用。
- 我们可以自由的把函数对象赋值给其他的名称并且勇冠任何引用调用它。
-
- '''
- #定制求和函数
- def mysum(L):
- print(L)
- if not L:
- return 0
- else:
- return L[0] + mysum(L[1:])
- print(mysum([5,6,7,8,9,10])) #45
-
- def mysum2(T):
- return T[0] if len(T) == 1 else T[0] + mysum2(T[1:])
- print(mysum2(['t','a','l','e','n']))
- print(mysum2(['ad','vs','ok']))
- #def mysum3(C):
- # first, *rest = C
- # return first if not rest else first + mysum3(rest)
- #print(mysum3(['t','a','l','e','n']))
- #print(mysum3(['ad','vs','ok']))
-
- #隐性递归
- def mysum4(L):
- if len(L) == 0:
- return 0
- else:
- return nonemputy(L)
- def nonemputy(L):
- return L[0] + mysum4(L[1:])
-
- print(mysum4([1.1,2.2,3.3]))
-
- #循环语句VS递归,python循环会再自然一些,迭代也比递归在内存空间和执行时间方面效率高一些。
- L=[1,2,3,4,5]
- sum =0
- while L:
- sum += L[0]
- L=L[1:]
- print(sum)
-
- L=[1,2,3,4,5,6]
- sum=0
- for x in L:
- sum +=x
- print(sum)
-
- #处理任意结构
- L=[1,2,[3,4,[5,6],7,8],9]
- M=[1,[2,[3,[4,[5]]]]]
- def sumtree(L):
- tot=0
- for x in L:
- if isinstance(x,list):
- tot += sumtree(x)
- else:
- tot += x
- return tot
- print(sumtree(L))
- print(sumtree(M))
- #函数间接调用
- def echo(message):
- print(message)
- echo('直接调用')
- x=echo
- x('赋值调用')
- def indirect(func,arg):
- func(arg)
- indirect(echo,'作为参数调用')
- #python复合类型
- T=[(echo,'spam!'),(echo,'ham!')]
- for (func,arg) in T:
- func(arg)
- #函数内省
- print(indirect.__name__)
- print(dir(indirect))
- print(dir(indirect.__code__))
- print(indirect.__code__.co_argcount)
- print(indirect.__code__.co_varnames)
-
- #函数属性 用户自定义附加
- # 属性与对象相关而不是与作用域相关,但是直接效果是类似。
- indirect.count=100
- print(indirect.count) #100
- print(dir(indirect)) #包含有count
-
- #python3.0新功能
- #函数注解
- #函数注解编写在def头部行,注解只对def有效,对lambda无效。
- #对于参数,它们出现在紧随参数名之后的冒号之后;
- #对于返回值,它们编写于紧跟在参数列表之后的一个->之后。
- #注解收集到__annotations__
- #def funcA(a:'spam',b:(1,10)=10,c:float=5) -> int:
- # return a+b+c
- #print(func(1,2,3)) #6
- #print(funcA.__annotations__) #{'c': class 'float'>, 'return': class 'int'>, 'a': 'spam', 'b': (1, 10)}
- #注解出现在默认值之前,如c:float=5
- #特别注意:函数一个参数如果有一个有默认值,则其后面的参数必须带有默认值否则会报SyntaxError: non-default argument follows default argument
-
-
- #匿名函数:lambda 函数对象的表达式形式,返回一个函数对象,这个函数没有函数名。更简洁短小。
- #lambda表达式:
- #lambda argument1,argument2,argument3,...,argumentN :expression using arguments
- #1.lambda是一个表达式,而不是一个语句
- #2.lambda的主体是一个单个的表达式,而不是一个代码块。
- #lambda是为编写简单函数而设计的,而def用来处理更大的任务。
-
- def knights():
- title = 'Sir'
- action = (lambda x : title + ' ' + x)
- return action
- act=knights()
- print(act('talen'))
-
- #lambda通常用来编写跳转表(jump table),也就是行为的列表或字典,能够按需执行相应的动作。
- L=[
- lambda x: x ** 2,
- lambda x: x ** 3,
- lambda x: x ** 4
-
- ]
- for f in L:
- print(f(2))
- print(L[0](3))
-
- #当需要把小段的可执行代码编写进def语句从语法上不编写进的地方时,lambda表达式做为def的一种速写来说是最有用的。
- key='own'
- print({
- 'talen':lambda x :2 +x ,
- 'own':lambda x : 2 * x ,
- 'one':lambda x : 2 ** x ,
- }[key](3))
-
- lower=lambda x,y:x if xy else y
- print(lower('cc','aa'))
- print(lower('cc','dd'))
-
- #简洁优于复杂
- #嵌套lambda和作用域
- #lambda可以获取嵌套函数作用域的变量名。
- #lambda可以获取任意上层lambda的变量名。
- #出于可读性的要求,尽量避免使用嵌套的lambda。
- #在序列中映射函数:map
- #map函数会对一个序列对象中的每一个元素应用被传入的函数,并且返回一个包含了所有函数调用结果的一个列表。
- #它虽不太常用,但运行速度比列表解析要快。
- counters=[1,2,3,4,5]
- def func(x):
- return x + 100
- print(map(func,counters)) #对counters列表中的每一个元素执行func函数操作。
- #由于map期待传入一个函数,这恰好是lambda经常出现的地方。
- print(map((lambda x : x + 10),counters))
- #也可以自己写一个map函数
- def mymap(func,seq):
- res=[]
- for x in seq:
- res.append(func(x))
- return res
- print(mymap(func,counters))
- print(mymap(func,[100,200,300,400]))
-
- print(pow(2,3))
- print(map(pow,[1,2,3],[2,3,4]))#将后面2个列表中的元素一一对应给pow函数。
-
- #函数式编程工具:filter和reduce
- #函数式编程就是对序列应用一些函数的工具。
- print(list(range(-10,10)))
- print(list(filter((lambda x :x > 2),range(-10,10))))#对一个序列执行过滤大于2的元素并列表化。
-
- from functools import reduce
- print(reduce((lambda x,y:x+y),[1,2,3,4]))#reduce调用,计算了列表中的所有元素和并返回一个值
-
- #等价自写
- def myreduce(func,seq):
- res=seq[0]
- for next in seq[1:]:
- res = func(res,next)
- return res
- print(myreduce((lambda x,y: x +y),[1,2,3,4]))
结果
点击(此处)折叠或打开
- /usr/bin/python2.7 /home/talen/PycharmProjects/untitled/t19.py
- [5, 6, 7, 8, 9, 10]
- [6, 7, 8, 9, 10]
- [7, 8, 9, 10]
- [8, 9, 10]
- [9, 10]
- [10]
- []
- 45
- talen
- advsok
- 6.6
- 15
- 21
- 45
- 15
- 直接调用
- 赋值调用
- 作为参数调用
-
-
- indirect
- ['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
- ['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']
- 2
- ('func', 'arg')
- 100
- ['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
- Sir talen
- 4
- 8
- 16
- 9
- 6
- aa
- cc
- [101, 102, 103, 104, 105]
- [11, 12, 13, 14, 15]
- [101, 102, 103, 104, 105]
- [200, 300, 400, 500]
- 8
- [1, 8, 81]
- [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- [3, 4, 5, 6, 7, 8, 9]
- 10
- 10
-
- Process finished with exit code 0