{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Python 简介\n", "\n", "本节只介绍 Python 的基础语法,原则上不涉及任何库的使用。\n", "\n", "本节适合通读,而并不需要读者记录任何用法;本节中的所有内容会在后续章节中系统地进行介绍。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 编程人员快速上手" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "注意\n", " \n", "本节专为有过其他编程语言经验的技术人员设置;如果您是编程新手,可以向下滚动以跳过此节。\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "如果您曾经使用过其他编程语言,那么您可能需要知道 Python 的以下特性。\n", "\n", "- Python 是一门**解释型语言**(Interpreted language),代码由解释器(Interperter)直接逐行执行。与之相对的是编译型语言(Complied language),例如 C++;编译型语言的代码会先被编译器(Compiler)编译为机器码,然后执行。\n", "- Python 是一门**动态类型语言**(Dynamically typed language)——这意味着它在运行时(而不是编译时)才进行类型检查。它同时也是*强类型**(Strongly typed)的。\n", "- Python 中的函数是第一类对象(First class object),可以赋值给变量或容器、作为参数传入、作为返回值。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "用一段列表扼要介绍 Python 的语法特点:\n", "\n", "- 代码文件的扩展名是 `.py`\n", "- 变量/函数声明:\n", " - 赋初值,但无需指明类型关键字(函数无需指明返回值类型)\n", " - 没有硬常量类型\n", "- 行尾标识:无(没有分号!)\n", "- 变量名/函数名:\n", " - 大小写敏感,比如 `y` 与 `Y` 是两个变量\n", " - 通常使用小写字母 `a~z`,大写字母 `A~Z`,数字 `0~9` 以及下划线 `_` 组成\n", " - 不可使用 Python 原生的关键字(保留字),参考 [Keywords - Python](https://docs.python.org/3.8/reference/lexical_analysis.html#keywords) 官方文档。目前版本的关键字有:\n", " \n", " ```\n", " False await else import pass\n", " None break except in raise\n", " True class finally is return\n", " and continue for lambda try\n", " as def from nonlocal while\n", " assert del global not with\n", " async elif if or yield\n", " ```\n", "\n", "- 数据类型:简要介绍几种易与其他语言类比的数据类型。\n", " \n", " 1. 字符串 str:Python 没有单字符类型,单个字符仅仅是长度为 1 的字符串。\n", " 2. 列表 list:类似于数组、矩阵类型。\n", " 3. 字典 dict:键值对数据,类似于哈希表。\n", " 4. 整型 int,浮点型 float:常见的数字类型。\n", " 5. 布尔型 bool:逻辑类型,真或假。\n", " 6. 空 NoneType:对应保留字 `None`,类似于某些语言的 null 或 nil\n", " \n", "- 注释:行内注释使用井号 `#` 开启,例如 `a = 1 #comment`\n", "- 代码块:\n", " - 按缩进识别,第一层四个空格,第二层八个,以此类推\n", " - 代码块的内部结构以冒号开启,比如\n", " \n", " ```python \n", " if i < n:\n", " i += 1\n", " else:\n", " m = i\n", " ```\n", " \n", " - 无需花括号!\n", " - 在代码块结束时,不需要 end,也不需要额外的空白行\n", "- 全局标记:用 `global` 关键字在函数内标记一个变量,它的值会被保留到函数外(全局)。参考下例:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n" ] } ], "source": [ "a = 1\n", "def f():\n", " global a\n", " a = 2\n", "f()\n", "print(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 引言:从数字运算熟悉语法\n", "\n", "Python 的基础语法非常简单,让我们先从数字开始吧。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 变量的使用\n", "\n", "Python 中的变量不需要声明类型,可以直接赋值使用。比如,我们现在记录两个数字到变量 `a` 与 `b`:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "a = 5\n", "b = 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "上面两行代码就创建了两个整型变量 `a` 与 `b`。一些注意点:\n", "\n", "- Python 的赋值符号是简单的等号 `=`,而不是 `:=` 之类的东西\n", "- 每一行是一条语句。语句末尾不需要 `;` 或任何断行标记\n", "- 行内的空格不是必需的,只是为了更好的可读性。你也可以把 `a = 5` 紧凑地写为 `a=5`\n", "- 行首不可以有空格,除非正使用代码块" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 数字运算\n", "\n", "数字间的四则运算与大多数编程语言一样,加、减、乘、除分别是 `+`、`-`、`*`、`/`:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(7, 3, 10, 2.5)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a + b, a - b, a * b, a / b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "上述非 print 的写法只在交互式的 Python 命令行中有效,在执行 `.py` 文件时是不会输出结果的。正规的写法是利用 `print()` 函数,将它们依次打印到屏幕(`print()` 函数默认以空格分隔每一项)。\n", "\n", "- 函数 `print` 被调用了,其右侧的括号内是函数的输入参数。\n", "- 函数的各个输入参数之间用英文逗号分隔" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "7 3 10 2.5\n" ] } ], "source": [ "print(a + b, a - b, a * b, a / b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "函数 `print()` 可以用 `sep` 参数来指定以什么分隔符来分隔多个要输出的项(默认是空格)。比如用换行符 `\\n` :" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "7\n", "3\n", "10\n", "2.5\n" ] } ], "source": [ "print(a + b, a - b, a * b, a / b, sep='\\n')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "稍微复杂一点的数字运算是整除、取余和乘方,分别是 `//`、`%`、`**`:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 1 25\n" ] } ], "source": [ "print(a // b, a % b, a ** b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在同时计算整除与取余时,Python 还提供了一个函数 `divmod()`,它返回一个长度为 2 的元组,即 `divmod(x, y) = (x//y, x%y)`:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(2, 1)\n" ] } ], "source": [ "print(divmod(a, b))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在 Python 中,圆括号代表高优先级;方括号与花括号在 Python 中有另外的含义,因此在做数学运算的时候,你只能不断地叠用圆括号:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(2 + (2 * 2)) // 5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 存储计算结果\n", "\n", "要将结果储存起来,使用之前介绍的赋值号 `=`:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "7 (2, 1) 2 1\n" ] } ], "source": [ "c = a + b\n", "d = divmod(a, b)\n", "e, f = divmod(a, b)\n", "print(c, d, e, f)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 在 Python 中,用井号(Sharp 号)`#` 来开始一个行内注释,它右侧的内容会被注释掉。\n", "- 赋值不必是一对一的;如果赋值号右侧的表达式返回一个长度为 n 的元组,那么左侧也可以用 n 个由逗号连接的变量来接受按顺序拆分的结果。\n", " - 上例中 `d` 接受了一个长度为 2 元组的返回值,因此 `d` 是一个的元组,值是 `(2,1)`\n", " - 上例中 `e, f` 接受了元组 `(2,1)` 的赋值,因此 `e` 被赋值为 2, `f` 被赋值为 1。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 注释\n", "\n", "Python 用 `#` 符号来将本行内该符号右侧的内容标记为注释,方便用户输入说明性的文字。" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 3\n" ] } ], "source": [ "a = 1\n", "# a = 2\n", "b = 3 # We know b > a\n", "print(a, b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 代码块\n", "\n", "Python 中的代码块(比如函数的定义、判断语句的内容)并不使用花括号包裹,也不用 end 作为结尾.\n", "\n", "- 开启代码块的行一般以英文冒号结尾,比如 if, for 语句\n", "- Python 使用 **四个空格** 的行首缩进来标出代码块的层级\n", "- 代码块每嵌套一次,就在行首再多添加四个空格\n", "- 代码块以行首减少四个空格的新航来自然结束" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "Outside the block\n" ] } ], "source": [ "x = 2\n", "if x > 1:\n", " print(x)\n", "print(\"Outside the block\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "嵌套的代码块:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Block\n", "Nested block\n", "Block\n", "Outside\n" ] } ], "source": [ "x = 2\n", "if x > 1:\n", " print(\"Block\")\n", " if x < 3:\n", " print(\"Nested block\")\n", " print(\"Block\")\n", "print(\"Outside\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 加载库\\*\n", "\n", "Python 的丰富生态由多种多样的库构成,它们提供了许多外部的功能。要使用库,需要在调用库的函数前加载。\n", "\n", "- 使用 `import lib` 来加载名为 lib 的库\n", "- 使用 `lib.func()` 来使用 lib 库中定义的函数 func\n", "\n", "这些库中,一部分是标准库,它们随 Python 安装,比如标准数学库 `math` :" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.999999327347282\n" ] } ], "source": [ "import math\n", "\n", "print(math.log(2.71828))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "另一些库是外部库,它们是由社区提供的,需要先安装到本地才能加载。关于如何安装外部库,参考上一章的 pip 安装命令。\n", "\n", "在安装了外部库后,它们就可以像上面的标准库一样加载与使用了:\n", "\n", "- 加载时的 `as` 命令可以给库设置一个自定义的名称。" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.718281828459045\n" ] } ], "source": [ "import numpy as np\n", "\n", "print(np.exp(1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "有时我们只需要用到库中的个别函数,这时候可以用 `from ... import` 语句:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.0\n", "2.718281828459045\n" ] } ], "source": [ "from numpy import pi, sin\n", "from numpy import exp as npexp\n", "\n", "print(sin(pi/2), npexp(1), sep='\\n')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "上例中引入了 numpy 库中的 pi 常量与 sin 函数(需要注意不要与已有的变量/函数名冲突),还引入了 exp 函数并设置 npexp 为它的自定义名称。\n", "\n", "更多的关于库的使用,参考后文的相关章节。" ] } ], "metadata": { "celltoolbar": "Raw Cell Format", "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.3" }, "toc": { "base_numbering": 1, "nav_menu": { "height": "372px", "width": "431px" }, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }