>>> deffib(n): # write Fibonacci series up to n ... """Print a Fibonacci series up to n.""" ... a, b = 0, 1 ... while a < n: ... print(a, end=' ') ... a, b = b, a+b ... print() ... >>> # Now call the function we just defined: ... fib(2000) 011235813213455891442333776109871597
defask_ok(prompt, retries=4, reminder='Please try again!'): whileTrue: ok = input(prompt) if ok in ('y', 'ye', 'yes'): returnTrue if ok in ('n', 'no', 'nop', 'nope'): returnFalse retries = retries - 1 if retries < 0: raise ValueError('invalid user response') print(reminder)
这个函数可以通过几种方式调用:
只给出必需的参数:ask_ok(‘Do you really want to quit?’)
给出一个可选的参数:ask_ok(‘OK to overwrite the file?’, 2)
或者给出所有的参数:ask_ok(‘OK to overwrite the file?’, 2, ‘Come on, only yes or no!’)
多次调用默认参数会共享
1 2 3 4 5 6 7
def f(a, L=[]): L.append(a) return L
print(f(1)) print(f(2)) print(f(3))
位置参数和关键字参数(函数调用)
也可以使用形如 kwarg=value 的 关键字参数 来调用函数。例如下面的函数:
1 2 3 4 5
defparrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'): print("-- This parrot wouldn't", action, end=' ') print("if you put", voltage, "volts through it.") print("-- Lovely plumage, the", type) print("-- It's", state, "!")
parrot() # required argument missing parrot(voltage=5.0, 'dead') # non-keyword argument after a keyword argument parrot(110, voltage=220) # duplicate value for the same argument parrot(actor='John Cleese') # unknown keyword argument
在函数调用中,关键字参数必须跟随在位置参数的后面。
传递的所有关键字参数必须与函数接受的其中一个参数匹配(比如 actor 不是函数 parrot 的有效参数),它们的顺序并不重要。
defcheeseshop(kind, *arguments, **keywords): print("-- Do you have any", kind, "?") print("-- I'm sorry, we're all out of", kind) for arg in arguments: print(arg) print("-" * 40) for kw in keywords: print(kw, ":", keywords[kw])
它可以像这样调用:
1 2 3 4 5
cheeseshop("Limburger", "It's very runny, sir.", "It's really very, VERY runny, sir.", shopkeeper="Michael Palin", client="John Cleese", sketch="Cheese Shop Sketch")
当然它会打印:
1 2 3 4 5 6 7 8
-- Do you have any Limburger ? -- I'm sorry, we're all out of Limburger It's very runny, sir. It's really very, VERY runny, sir. ---------------------------------------- shopkeeper : Michael Palin client : John Cleese sketch : Cheese Shop Sketch
>>> pos_only_arg(arg=1) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: pos_only_arg() got an unexpected keyword argument 'arg'
第三个函数 kwd_only_args 在函数定义中通过 * 指明仅允许关键字参数:
1 2 3 4 5 6 7 8
>>> >>> kwd_only_arg(3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given
>>> kwd_only_arg(arg=3) 3
而最后一个则在同一函数定义中使用了全部三种调用方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
>>> >>> combined_example(1, 2, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: combined_example() takes 2 positional arguments but 3 were given
>>> >>> list(range(3, 6)) # normal call with separate arguments [3, 4, 5] >>> args = [3, 6] >>> list(range(*args)) # call with arguments unpacked from a list [3, 4, 5]
同样的方式,字典可使用 ** 操作符 来提供关键字参数:
1 2 3 4 5 6 7 8 9
>>> >>> defparrot(voltage, state='a stiff', action='voom'): ... print("-- This parrot wouldn't", action, end=' ') ... print("if you put", voltage, "volts through it.", end=' ') ... print("E's", state, "!") ... >>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"} >>> parrot(**d) -- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
使用*和**来对元组参数和字典参数进行解包,与定义复合参数的函数相对应。
Lambda表达式(函数定义)
可以用 lambda 关键字来创建一个小的匿名函数。这个函数返回两个参数的和: lambda a, b: a+b 。Lambda函数可以在需要函数对象的任何地方使用。它们在语法上限于单个表达式。从语义上来说,它们只是正常函数定义的语法糖。与嵌套函数定义一样,lambda函数可以引用所包含域的变量:
1 2 3 4 5 6 7 8 9
>>> >>> defmake_incrementor(n): ... returnlambda x: x + n ... >>> f = make_incrementor(42) >>> f(0) 42 >>> f(1) 43