604 lines
14 KiB
Plaintext
604 lines
14 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# 函数"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"函数,实际上是可被调用的完整的程序。它具备输入、处理、输出的功能。\n",
|
||
"\n",
|
||
"函数包含两个方面:\n",
|
||
"\n",
|
||
"> * 它的**输入**是怎么构成的(都有哪些参数?如何指定?);\n",
|
||
"> * 以及它的**输出**是什么(返回值究竟是什么?)……\n",
|
||
"\n",
|
||
"```python\n",
|
||
"def cow(grass)\n",
|
||
" return milk\n",
|
||
"```\n",
|
||
"\n",
|
||
"我们使用函数的过程中,我们常常*有意忽略*它的内部如何完成从输入到输出之间的*处理过程* —— 这就好像我们平日里用灯泡一样,大多数情况下,我们只要知道开关的使用方法就够了 —— 至于为什么按到这个方向上灯会亮,为什么按到另外一个方向上灯会灭,并不是我们作为用户必须关心的事情……\n",
|
||
"\n",
|
||
"当然,如果你是设计开关的人就不一样了,你必须知道其中的运作原理;但是,最终,你还是希望你的用户用最简单方便的操作界面,而不是必须搞懂所有原理才能够使用你所设计的产品……\n",
|
||
"\n",
|
||
"当我们用 Python 编程的时候,更多的情况下,我们只不过是在使用别人已经写好的函数."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"toc-hr-collapsed": true
|
||
},
|
||
"source": [
|
||
"## 示例 print()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### 基本的使用方法"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"它最基本的作用就是把传递给它的值输出到屏幕上,如果不给它任何参数,那么它就输出一个空行:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"line 1st\n",
|
||
"line 2nd\n",
|
||
"\n",
|
||
"line 4th\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"print('line 1st')\n",
|
||
"print('line 2nd')\n",
|
||
"print()\n",
|
||
"print('line 4th')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"也可以传递多个参数,参数之间用 `,` 分开,它就会把那些值逐个输出到屏幕,每个值之间默认用空格分开。"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Hello, jack mike ... and all you guys!\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"print('Hello,', 'jack', 'mike', '...', 'and all you guys!')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"当我们想把变量或者表达式的值插入字符串中的时候,可以用 f-string:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 12,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Ann is 22 years old.\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"name = 'Ann'\n",
|
||
"age = '22'\n",
|
||
"print(f'{name} is {age} years old.')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"但这并不是 `print()` 这个函数的功能,这实际上是 [`f-string`](https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting) 的功能,`f-string` 中用花括号 `{}` 括起来的部分是表达式,最终转换成字符串的时候,那些表达式的值(而不是变量或者表达式本身)会被插入相应的位置……"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 11,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"'Ann is 22 years old.'"
|
||
]
|
||
},
|
||
"execution_count": 11,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"name = 'Ann'\n",
|
||
"age = '22'\n",
|
||
"f'{name} is {age} years old.'"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"所以,`print(f'{name} is {age} years old.')` 这一句中,函数 `print()` 完成的还是它最基本的功能:给它什么,它就把什么输出到屏幕上。"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### print() 的官方文档说明"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"\n",
|
||
"最必须读懂的部分,就是这一行:\n",
|
||
"\n",
|
||
"> `print(*object, sep=' ', end='\\n', file=sys.stdout, flush=False)` <a href='#fn1' name='fn1b'><sup>[1]</sup></a>\n",
|
||
"\n",
|
||
"先只注意那些有着 `=` 的参数,`sep=' '`、`end='\\n'`\n",
|
||
"\n",
|
||
"这其中,先关注这三个 `sep=' '`、`end='\\n'`\n",
|
||
"\n",
|
||
"> * `sep=' '`:接收多个参数之后,输出时,分隔符号默认为空格,`' '`;\n",
|
||
"> * `end='\\n'`:输出行的末尾默认是换行符号 `'\\n'`;\n",
|
||
"\n",
|
||
"也就是说,这个函数中有若干个具有默认值的参数,即便我们在调用这个函数的时候,就算没有指定它们,它们也存在于此。\n",
|
||
"\n",
|
||
"即,当我们调用 `print('Hello', 'world!')` 的时候,相当于我们调用的是 `print('Hello', 'world!', sep=' ', end='\\n', file=sys.stdout, flush=False)`"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Hello world!\n",
|
||
"Hello-world!\tHello~world!\n",
|
||
"Hello\n",
|
||
"world!\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"print('Hello', 'world!') # 下一行的输出和这一行相同\n",
|
||
"print('Hello', 'world!', sep='-', end='\\t')\n",
|
||
"print('Hello', 'world!', sep='~') # 上一行的末尾是 \\t,所以,这一行并没有换行显示\n",
|
||
"print('Hello', 'world!', sep='\\n') # 参数之间用换行 \\n 分隔 "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"> `print()` 这个函数的返回值是 `None` —— 注意,它向屏幕输出的内容,与 `print()` 这个函数的返回值不是一回事。\n",
|
||
"\n",
|
||
"做为例子,看看 `print(print(1))` 这个语句 —— `print()` 这个函数被调用了两次,第一次是 `print(1)`,它向屏幕输出了一次,完整的输出值实际上是 `str(1) + '\\n'`,而后返回一个值,`None`;而第二次调用 print(),这相当于是向屏幕输出这个 `None`:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"1\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"print(1)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"1\n",
|
||
"None\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"print(print(1))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 关键字参数"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"在 Python 中,函数的参数,有两种:\n",
|
||
"> * **位置参数**(Positional Arguments,在官方文档里常被缩写为 *arg*)\n",
|
||
"> * **关键字参数**(Keyword Arguments,在官方文档里常被缩写为 *kwarg*)\n",
|
||
"\n",
|
||
"在函数定义中,带有 `=` 的,即,已为其设定了默认值的参数,叫做 Keyword Arguments,其它的是 Positional Arguments。\n",
|
||
"\n",
|
||
"在调用有 Keyword Arguments 的函数之时,如若不提供这些参数,那么参数在执行时,启用的是它在定义的时候为那些 Keyword Arguments 所设定的默认值;如若提供了这些参数的值,那么参数在执行的时候,启用的是接收到的相应值。\n",
|
||
"\n",
|
||
"比如,`sorted()` 函数,它的定义如下:\n",
|
||
"\n",
|
||
"> `sorted(iterable, *, key=None, reverse=False)`\n",
|
||
"\n",
|
||
"现在先只关注它的 Keyword Arguments,`reverse`:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 31,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"['a', 'b', 'c', 'd']"
|
||
]
|
||
},
|
||
"execution_count": 31,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"['d', 'c', 'b', 'a']"
|
||
]
|
||
},
|
||
"execution_count": 31,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"from IPython.core.interactiveshell import InteractiveShell\n",
|
||
"InteractiveShell.ast_node_interactivity = \"all\"\n",
|
||
"\n",
|
||
"sorted('abdc')\n",
|
||
"sorted('abdc', reverse=True)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 位置参数"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"\n",
|
||
"它接收且必须接收两个参数。\n",
|
||
"\n",
|
||
"> * 当你调用这个函数的时候,括号里写的第一个参数,是被除数,第二个参数是除数 —— 此为该函数的输入;\n",
|
||
"> * 而它的返回值,是一个元组(Tuple,至于这是什么东西,后面讲清楚),其中包括两个值,第一个是商,第二个是余 —— 此为该函数的输出。"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"(3, 2)"
|
||
]
|
||
},
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"3"
|
||
]
|
||
},
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"2"
|
||
]
|
||
},
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"(0, 3)"
|
||
]
|
||
},
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"0"
|
||
]
|
||
},
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"3"
|
||
]
|
||
},
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"(5, 0)"
|
||
]
|
||
},
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"0"
|
||
]
|
||
},
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"from IPython.core.interactiveshell import InteractiveShell\n",
|
||
"InteractiveShell.ast_node_interactivity = \"all\"\n",
|
||
"\n",
|
||
"divmod(11, 3)\n",
|
||
"a, b = divmod(11, 3)\n",
|
||
"a\n",
|
||
"b\n",
|
||
"\n",
|
||
"divmod(3, 11)\n",
|
||
"a, b = divmod(3, 11)\n",
|
||
"a\n",
|
||
"b\n",
|
||
"\n",
|
||
"tup = divmod(15 , 3)\n",
|
||
"tup\n",
|
||
"tup[1]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"toc-hr-collapsed": false
|
||
},
|
||
"source": [
|
||
"## 可选位置参数"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"有些函数,如 `pow()`,有**可选的位置参数**(Optional Positional Arguments)。\n",
|
||
"\n",
|
||
"于是,`pow()` 有两种用法,各有不同的结果:\n",
|
||
"\n",
|
||
"> * `pow(x, y)` —— 返回值是 `x ** y`\n",
|
||
"> * `pow(x, y, z)` —— 返回值是 `x ** y % z`\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 40,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"8"
|
||
]
|
||
},
|
||
"execution_count": 40,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"0"
|
||
]
|
||
},
|
||
"execution_count": 40,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"from IPython.core.interactiveshell import InteractiveShell\n",
|
||
"InteractiveShell.ast_node_interactivity = \"all\"\n",
|
||
"\n",
|
||
"pow(2, 3)\n",
|
||
"pow(2, 3, 4)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Class 也是函数"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"虽然你现在还不一定知道 Class 究竟是什么,但在阅读官方文档的时候,遇到一些内建函数前面写着 Class,比如 `Class bool([x])`,千万别奇怪,因为 Class 本质上来看就是一种特殊类型的函数,也就是说,它也是函数:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 44,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"False"
|
||
]
|
||
},
|
||
"execution_count": 44,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"True"
|
||
]
|
||
},
|
||
"execution_count": 44,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"True"
|
||
]
|
||
},
|
||
"execution_count": 44,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"False"
|
||
]
|
||
},
|
||
"execution_count": 44,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"False"
|
||
]
|
||
},
|
||
"execution_count": 44,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"from IPython.core.interactiveshell import InteractiveShell\n",
|
||
"InteractiveShell.ast_node_interactivity = \"all\"\n",
|
||
"\n",
|
||
"bool()\n",
|
||
"bool(3.1415926)\n",
|
||
"bool(-3.1415926)\n",
|
||
"bool(1 == 2)\n",
|
||
"bool(None)"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.8.2"
|
||
},
|
||
"toc-autonumbering": true
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 2
|
||
}
|