# 自定义函数

Python中使用def来定义函数，并使用return来返回特定的值。

def my_function(x, y, z):
if z > 1:
return z * (x + y)
else:
return z / (x + y)

def fib(n):
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
# 调用函数
fib(1000)

## 参数的默认值

def my_function(x, y, z=10):
if z > 1:
return z * (x + y)
else:
return z / (x + y)

def f(a, L=[]):
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
# 输出
[1]
[1, 2]
[1, 2, 3]

def f(a, L=None):
if L is None:
L = []
L.append(a)
return L

## 关键字参数

def my_function(x, y, z=10):
if z > 1:
return z * (x + y)
else:
return z / (x + y)

my_function(1,y=3,z=5)
my_function(1,y=3)

my_function(y=3,1)

>>> def function(a):
...     pass
...
>>> function(0, a=0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: function() got multiple values for keyword argument 'a'

In [69]: def fa(a=100,b,c=200):
...:     pass
File "<ipython-input-69-d5678b64f352>", line 1
def fa(a=100,b,c=200):
^
SyntaxError: non-default argument follows default argument

In [70]: def fa(a,b=100,c=200):
...:     pass
...:
In [71]: fa(a=100,30)
File "<ipython-input-71-5a229b8e420e>", line 1
fa(a=100,30)
^
SyntaxError: positional argument follows keyword argument

*arguments用来接收所有多余的非关键词参数。而**keywords用来接收所有额外的关键词参数。

def cheeseshop(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])

cheeseshop("Limburger", "It's very runny, sir.",
"It's really very, VERY runny, sir.",
shopkeeper="Michael Palin",
client="John Cleese",
sketch="Cheese Shop Sketch")

-- 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

## 特殊参数

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
-----------    ----------     ----------
|             |                  |
|        按位置或者关键词           |
|                                - 只允许按关键词传递
-- 只允许按位置传递

>>> def standard_arg(arg):
...     print(arg)
...
>>> def pos_only_arg(arg, /):
...     print(arg)
...
>>> def kwd_only_arg(*, arg):
...     print(arg)
...
>>> def combined_example(pos_only, /, standard, *, kwd_only):
...     print(pos_only, standard, kwd_only)

## 参数解包

* 操作符 可以用来解包列表和元组。

>>> 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]

** 操作符 可以用来解包字典。

>>> def parrot(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)

## Lambda

>>> def make_incrementor(n):
...     return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43

>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> pairs.sort(key=lambda pair: pair[1])
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]

## 函数标注

>>> def f(ham: str, eggs: str = 'eggs') -> str:
...     print("Annotations:", f.__annotations__)
...     print("Arguments:", ham, eggs)
...     return ham + ' and ' + eggs
...
>>> f('spam')
Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>}
Arguments: spam eggs
'spam and eggs'

+ 订阅