Files
ailearning/docs/da/023.md
2020-10-19 21:08:55 +08:00

436 lines
6.4 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 函数
## 定义函数
函数`function`,通常接受输入参数,并有返回值。
它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性。
In [1]:
```py
def add(x, y):
"""Add two numbers"""
a = x + y
return a
```
函数通常有一下几个特征:
* 使用 `def` 关键词来定义一个函数。
* `def` 后面是函数的名称,括号中是函数的参数,不同的参数用 `,` 隔开, `def foo():` 的形式是必须要有的,参数可以为空;
* 使用缩进来划分函数的内容;
* `docstring``"""` 包含的字符串,用来解释函数的用途,可省略;
* `return` 返回特定的值,如果省略,返回 `None`
## 使用函数
使用函数时,只需要将参数换成特定的值传给函数。
**Python**并没有限定参数的类型,因此可以使用不同的参数类型:
In [2]:
```py
print add(2, 3)
print add('foo', 'bar')
```
```py
5
foobar
```
在这个例子中,如果传入的两个参数不可以相加,那么**Python**会将报错:
In [3]:
```py
print add(2, "foo")
```
```py
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-6f8dcf7eb280> in <module>()
----> 1 print add(2, "foo")
<ipython-input-1-e831943cfaf2> in add(x, y)
1 def add(x, y):
2 """Add two numbers"""
----> 3 a = x + y
4 return a
TypeError: unsupported operand type(s) for +: 'int' and 'str'
```
如果传入的参数数目与实际不符合,也会报错:
In [4]:
```py
print add(1, 2, 3)
```
```py
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-ed7bae31fc7d> in <module>()
----> 1 print add(1, 2, 3)
TypeError: add() takes exactly 2 arguments (3 given)
```
In [5]:
```py
print add(1)
```
```py
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-5-a954233d3b0d> in <module>()
----> 1 print add(1)
TypeError: add() takes exactly 2 arguments (1 given)
```
传入参数时Python提供了两种选项第一种是上面使用的按照位置传入参数另一种则是使用关键词模式显式地指定参数的值
In [6]:
```py
print add(x=2, y=3)
print add(y="foo", x="bar")
```
```py
5
barfoo
```
可以混合这两种模式:
In [7]:
```py
print add(2, y=3)
```
```py
5
```
## 设定参数默认值
可以在函数定义的时候给参数设定默认值,例如:
In [8]:
```py
def quad(x, a=1, b=0, c=0):
return a*x**2 + b*x + c
```
可以省略有默认值的参数:
In [9]:
```py
print quad(2.0)
```
```py
4.0
```
可以修改参数的默认值:
In [10]:
```py
print quad(2.0, b=3)
```
```py
10.0
```
In [11]:
```py
print quad(2.0, 2, c=4)
```
```py
12.0
```
这里混合了位置和指定两种参数传入方式第二个2是传给 `a` 的。
注意,在使用混合语法时,要注意不能给同一个值赋值多次,否则会报错,例如:
In [12]:
```py
print quad(2.0, 2, a=2)
```
```py
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-12-101d0c090bbb> in <module>()
----> 1 print quad(2.0, 2, a=2)
TypeError: quad() got multiple values for keyword argument 'a'
```
## 接收不定参数
使用如下方法,可以使函数接受不定数目的参数:
In [13]:
```py
def add(x, *args):
total = x
for arg in args:
total += arg
return total
```
这里,`*args` 表示参数数目不定,可以看成一个元组,把第一个参数后面的参数当作元组中的元素。
In [14]:
```py
print add(1, 2, 3, 4)
print add(1, 2)
```
```py
10
3
```
这样定义的函数不能使用关键词传入参数,要使用关键词,可以这样:
In [15]:
```py
def add(x, **kwargs):
total = x
for arg, value in kwargs.items():
print "adding ", arg
total += value
return total
```
这里, `**kwargs` 表示参数数目不定,相当于一个字典,关键词和值对应于键值对。
In [16]:
```py
print add(10, y=11, z=12, w=13)
```
```py
adding y
adding z
adding w
46
```
再看这个例子,可以接收任意数目的位置参数和键值对参数:
In [17]:
```py
def foo(*args, **kwargs):
print args, kwargs
foo(2, 3, x='bar', z=10)
```
```py
(2, 3) {'x': 'bar', 'z': 10}
```
不过要按顺序传入参数,先传入位置参数 `args` ,在传入关键词参数 `kwargs`
## 返回多个值
函数可以返回多个值:
In [18]:
```py
from math import atan2
def to_polar(x, y):
r = (x**2 + y**2) ** 0.5
theta = atan2(y, x)
return r, theta
r, theta = to_polar(3, 4)
print r, theta
```
```py
5.0 0.927295218002
```
事实上,**Python**将返回的两个值变成了元组:
In [19]:
```py
print to_polar(3, 4)
```
```py
(5.0, 0.9272952180016122)
```
因为这个元组中有两个值,所以可以使用
```py
r, theta = to_polar(3, 4)
```
给两个值赋值。
列表也有相似的功能:
In [20]:
```py
a, b, c = [1, 2, 3]
print a, b, c
```
```py
1 2 3
```
事实上,不仅仅返回值可以用元组表示,也可以将参数用元组以这种方式传入:
In [21]:
```py
def add(x, y):
"""Add two numbers"""
a = x + y
return a
z = (2, 3)
print add(*z)
```
```py
5
```
这里的`*`必不可少。
事实上,还可以通过字典传入参数来执行函数:
In [22]:
```py
def add(x, y):
"""Add two numbers"""
a = x + y
return a
w = {'x': 2, 'y': 3}
print add(**w)
```
```py
5
```
## map 方法生成序列
可以通过 `map` 的方式利用函数来生成序列:
In [23]:
```py
def sqr(x):
return x ** 2
a = [2,3,4]
print map(sqr, a)
```
```py
[4, 9, 16]
```
其用法为:
```py
map(aFun, aSeq)
```
将函数 `aFun` 应用到序列 `aSeq` 上的每一个元素上,返回一个列表,不管这个序列原来是什么类型。
事实上,根据函数参数的多少,`map` 可以接受多组序列,将其对应的元素作为参数传入函数:
In [24]:
```py
def add(x, y):
return x + y
a = (2,3,4)
b = [10,5,3]
print map(add,a,b)
```
```py
[12, 8, 7]
```