Lesson 12
编程是会遇到逻辑重复的情况,通俗的讲,就是一个代码块可能会有多处要用到。这个时候,就需要函数了。
- 用def作为函数体的开头
- 其后是函数名(参数):
1 | dir() # inner functions in python |
['In',
'Out',
'_',
'_2',
'__',
'___',
'__builtin__',
'__builtins__',
'__doc__',
'__loader__',
'__name__',
'__package__',
'__spec__',
'_dh',
'_i',
'_i1',
'_i2',
'_i3',
'_ih',
'_ii',
'_iii',
'_oh',
'_sh',
'exit',
'f',
'get_ipython',
'quit']
1 | # a simple example |
1 | # by the way, 'f' is really a function |
<function __main__.f>
1 | # type in dir(), you will find that function 'f' has been in dir() |
['In',
'Out',
'_',
'_2',
'_3',
'__',
'___',
'__builtin__',
'__builtins__',
'__doc__',
'__loader__',
'__name__',
'__package__',
'__spec__',
'_dh',
'_i',
'_i1',
'_i2',
'_i3',
'_i4',
'_ih',
'_ii',
'_iii',
'_oh',
'_sh',
'exit',
'f',
'get_ipython',
'quit']
可以发现,刚刚定义的函数f已经被放入来dir()中。下面,我们来构造一个有具体意义的函数:
1 | def ping(): |
'Ping!'
下面介绍一个有意思的现象:
1 | x = ping() |
Ping!
1 | dir() |
['In',
'Out',
'_',
'_2',
'_3',
'_4',
'_6',
'__',
'___',
'__builtin__',
'__builtins__',
'__doc__',
'__loader__',
'__name__',
'__package__',
'__spec__',
'_dh',
'_i',
'_i1',
'_i2',
'_i3',
'_i4',
'_i5',
'_i6',
'_i7',
'_i8',
'_ih',
'_ii',
'_iii',
'_oh',
'_sh',
'exit',
'f',
'get_ipython',
'ping',
'quit',
'x']
将函数ping()指向x,你会发现,ping和x都被加入到dir()中去了。因此,函数可以通过等号来做映射。用print()等方法将函数的返回值直接打印出来,或者直接使用。这也从另一个方面说明了函数需要有输入输出运算关系的重要性,下面举例说明。
函数:计算球体体积 $V = \frac {4}{3} {\pi} r^3$
其中,$\pi$ 是python中math内建库里有的,$r$是我们需要自己定义的变量。
输入是半径,输出是球的体积,运算关系就是这个公式。
1 | import math |
['__doc__',
'__loader__',
'__name__',
'__package__',
'__spec__',
'acos',
'acosh',
'asin',
'asinh',
'atan',
'atan2',
'atanh',
'ceil',
'copysign',
'cos',
'cosh',
'degrees',
'e',
'erf',
'erfc',
'exp',
'expm1',
'fabs',
'factorial',
'floor',
'fmod',
'frexp',
'fsum',
'gamma',
'gcd',
'hypot',
'inf',
'isclose',
'isfinite',
'isinf',
'isnan',
'ldexp',
'lgamma',
'log',
'log10',
'log1p',
'log2',
'modf',
'nan',
'pi',
'pow',
'radians',
'sin',
'sinh',
'sqrt',
'tan',
'tanh',
'tau',
'trunc']
1 | math.pi |
3.141592653589793
1 | def volume(r): |
33.510321638291124
1 | volume() |
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-12-2e3c3020f7da> in <module>()
----> 1 volume()
TypeError: volume() missing 1 required positional argument: 'r'
此时,你就会发现,该函数如果不给输入变量$r$,就会报错。
下面举个升级版的例子:计算三角形的面积(输入:长、高;输出:三角形的面积;运算关系:$A=\frac {1}{2} b \cdot h$)
1 | def triangle_area(b, h): |
9.0
在python有一类函数中的变量被称为keyword arguments。
比如:1 inch = 2.54 cm, 1 foot = 12 inches。
1 | def cm(feet = 0, inches = 0): # default arguments |
152.4
1 | cm(inches = 70) |
177.8
1 | cm(feet = 5, inches = 70) |
330.20000000000005
1 | cm(inches = 70, feet = 5) |
330.20000000000005
1 | cm(5, 70) |
330.20000000000005
1 | cm(70,5) |
2146.2999999999997
这里就会发现,在使用该函数的时候,因为设定了变量的默认值,因此可以只给部分变量赋值。
其次,赋值的顺序并没有很大关系。最后是,如果不指定变量名,直接赋值,那么是按照函数声明时的变量顺序。
函数中的变量类型分两种:Keyword,Required。下面举个例子,直观的看它们的不同:
1 | def g(x=0,y): |
File "<ipython-input-28-76756415651c>", line 1
def g(x=0,y):
^
SyntaxError: non-default argument follows default argument
我们会得到“non-default argument follows default argument”这个错误,keyword argument也叫default argument,变量y也叫required argument。
1 | def g(y,x=0): |
5
如果将required argument放在前面,那么就不会报错,函数就能用了。
1 | g(5,x=7) |
12
Youtube source:
https://www.youtube.com/watch?v=bY6m6_IIN94&list=PLi01XoE8jYohWFPpC17Z-wWhPOSuh8Er-