“Python函数的基本使用”的版本间的差异
来自CloudWiki
(→函数的定义) |
(→函数的高级用法) |
||
第69行: | 第69行: | ||
>>> list(myMap(range(5), '-', 5)) | >>> list(myMap(range(5), '-', 5)) | ||
[-5, -4, -3, -2, -1] | [-5, -4, -3, -2, -1] | ||
+ | |||
+ | *注:python 的repr函数可以参考 http://www.runoob.com/python/python-func-repr.html | ||
*问题解决:用函数嵌套定义和递归实现帕斯卡公式C(n,i) = C(n-1, i) + C(n-1, i-1),进行组合数C(n,i)的快速求解。 | *问题解决:用函数嵌套定义和递归实现帕斯卡公式C(n,i) = C(n-1, i) + C(n-1, i-1),进行组合数C(n,i)的快速求解。 | ||
*[[文件:p5-2.png]] | *[[文件:p5-2.png]] |
2018年4月7日 (六) 07:29的版本
函数的定义
- 函数定义语法:
def <函数名>([参数列表]): '''注释''' <函数体> return <返回值列表>
函数的作用
- 将可能需要反复执行的代码封装为函数,并在需要该功能的地方进行调用,不仅可以实现代码复用,更重要的是可以保证代码的一致性,只需要修改该函数代码则所有调用均受到影响。
- 设计函数时,应注意提高模块的内聚性,同时降低模块之间的隐式耦合。
- 例1:生日歌
def happy(): print("Happy birthday to you!") def happyTo(name): print("Happy birthday, dear {}!".format(name)) happy( ) happyTo("Mike") print() happyTo("Lily")
注意事项
- 函数形参不需要声明类型,也不需要指定函数返回值类型
- 即使该函数不需要接收任何参数,也必须保留一对空的圆括号
- 括号后面的冒号必不可少
- 函数体相对于def关键字必须保持一定的空格缩进
- Python允许嵌套定义函数
例2:汇率计算器
def DolConvert(Num): Num =eval(Num); Dollar =Num /6; return Dollar Num = input("请输入人民币值: ") result = DolConvert(Num) print("能兑换的美元为:",result)
关于return语句
- 在Python中,定义函数时也不需要声明函数的返回值类型,而是使用return语句结束函数执行的同时返回任意类型的值,函数返回值类型与return语句返回表达式的类型一致。
- 不论return语句出现在函数的什么位置,一旦得到执行将直接结束函数的执行。
- 如果函数没有return语句、有return语句但是没有执行到或者执行了不返回任何值的return语句,解释器都会认为该函数以return None结束,即返回空值。
函数的调用过程
- 程序调用一个函数需要执行以下四个步骤。
1.调用程序,在调用处暂停执行。 2.在调用时将实参复制给函数的形参。 3.执行函数体语句。 4.函数调用结束后给出返回值,程序回到调用前的暂停处,继续执行。
- 例1:生日歌;例2:汇率计算器
函数的高级用法
函数嵌套定义
- Python允许函数的嵌套定义,在函数内部可以再定义另外一个函数。
>>> def myMap(iterable, op, value): #自定义函数 if op not in '+-*/': return 'Error operator' def nested(item): #嵌套定义函数 return eval(repr(item)+op+repr(value)) return map(nested, iterable) #使用在函数内部定义的函数 >>> list(myMap(range(5), '+', 5)) #调用外部函数,不需要关心其内部实现 [5, 6, 7, 8, 9] >>> list(myMap(range(5), '-', 5)) [-5, -4, -3, -2, -1]
- 注:python 的repr函数可以参考 http://www.runoob.com/python/python-func-repr.html
- 问题解决:用函数嵌套定义和递归实现帕斯卡公式C(n,i) = C(n-1, i) + C(n-1, i-1),进行组合数C(n,i)的快速求解。
def f2(n,i): cache2 = dict() def f(n,i): if n==i or i==0: return 1 elif (n,i) not in cache2: cache2[(n,i)] = f(n-1, i) + f(n-1, i-1) return cache2[(n,i)] return f(n,i)
- 使用标准库提供的缓冲机制进行改写和优化。
from functools import lru_cache @lru_cache(maxsize=64) def cni(n, i): if n==i or i==0: return 1 return cni(n-1, i) + cni(n-1, i-1)
可调用对象
- 函数属于Python可调用对象之一,由于构造方法的存在,类也是可调用的。像list()、tuple()、dict()、set()这样的工厂函数实际上都是调用了类的构造方法。另外,任何包含__call__()方法的类的对象也是可调用的。
- 下面的代码使用函数的嵌套定义实现了可调用对象的定义:
def linear(a, b): def result(x): #在Python中,函数是可以嵌套定义的 return a * x + b return result #返回可被调用的函数
- 下面的代码演示了可调用对象类的定义:
class linear: def __init__(self, a, b): self.a, self.b = a, b def __call__(self, x): #这里是关键 return self.a * x + self.b
- 使用上面的嵌套函数和类这两种方式中任何一个,都可以通过以下的方式来定义一个可调用对象:
taxes = linear(0.3, 2)
- 然后通过下面的方式来调用该对象:
taxes(5)
修饰器
- 修饰器(decorator)是函数嵌套定义的另一个重要应用。修饰器本质上也是一个函数,只不过这个函数接收其他函数作为参数并对其进行一定的改造之后使用新函数替换原来的函数。
- Python面向对象程序设计中的静态方法、类方法、属性等也都是通过修饰器实现的。
def before(func): #定义修饰器 def wrapper(*args, **kwargs): print('Before function called.') return func(*args, **kwargs) return wrapper def after(func): #定义修饰器 def wrapper(*args, **kwargs): result = func(*args, **kwargs) print('After function called.') return result return wrapper @before @after def test(): #同时使用两个修饰器改造函数 print(3) #调用被修饰的函数 test()