> For the complete documentation index, see [llms.txt](https://yangsx95.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yangsx95.gitbook.io/notes/programming-language/python.md).

# Python

python相关的基础代码位于Gitee的 <https://gitee.com/yangsx95/notes-python> 中。

### 搭建Python环境

#### windows下的python环境

前往 [官网](https://www.python.org/downloads/) 下载对应的python安装包，一路安装即可。

> 注意
>
> 在安装过程中会有选项，是否添加到环境变量中，勾选即可自动将python添加到环境变量中。

安装完成后，可以使用命令 `python` 检测是否安装成功。

> 如果你是用的是压缩版本，需要手动配置path环境变量， 直接将根路径设置到Path中即可。

#### 集成开发环境选择

1. 使用文本编辑器开发，然后通过 `python 文件名` 来运行
2. Pycharm，Jetbrains，笔者正在使用的一款开发环境
3. Aptana Studio，基于Eclipse基础上进行插件集改支持python开发
4. 使用IDEA或者Eclipse集成插件

#### 检测python的版本

```
python -V #注意V大写
Python 3.6.2
```

### Hello World

```python
print("Hello World");
```

使用 `python` 命令打开shell交互式解释器， 输入代码即可运行。

python命令参数：

选项参数-ddebug 解析时显示调试信息-O生成优化代码 .pyo 文件-S启动时不引入查找Python路径的位置-V输出Python版本号-X从 1.6版本之后基于内建的异常（仅仅用于字符串）已过时-c cmd执行 Python 脚本，并将运行结果作为 cmd 字符串file生成优化代码 .pyo 文件-h帮助

创建一个后缀为py的源码文件，使用python HelloWorld.py 运行python文件

### 交互式编程

我们可以在命令提示符中输入"Python"命令来启动Python解释器

### 脚本式编程

可以通过如下命令运行python脚本：

```python
python hello.py
```

### 编码

Python3源码默认以UTF-8为编码，所有字符串都是Unicode字符串。如果要切换编码，可以在源文件中指定：

```python
# -*- coding: cp-1252 -*-
```

### 标识符(变量命名规则)

1. 不可使用保留字
2. 首字符必须是字母或者下划线
3. 其他字符可以有字母下划线和数字组成
4. 大小写敏感

> 规则和Java相同

#### 保留字

python提供了 keyword模块，可以列举出当前版本的所有保留字：

```python
>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
```

#### 注释

单行注释： `#` sharp开头。

多行注释： 多个 `#` 开头，或者使用 `''' '''` 或者 `""" """`

```python
# 我是注释
'''
我是多行注释
'''
"""
我是多行注释
"""
```

#### 可选的分号

在语句结束时，可以使用换行表示语句结束，可以替代分号。

#### 行与缩进

1. python不需要大括号
2. 使用缩进表示代码块
3. 同一个代码块，缩进必须相同
4. 如果缩进不同，会抛出错误： `IndentationError: unindent does not match any outer indentation level`

```python
if True:
    print("Answer")
    print("True")
else:
    print("Answer")
    print("False")
```

#### 代码组

缩进相同的一组语句构成一个代码块，我们称之 **代码组**。

```python
if expression :
   suite
elif expression :
   suite
else :
   suite
```

#### 多行语句

如果语句过长，我们可以使用反斜杠来实现多行语句：

```java
total = item_one + \
        item_two + \
        item_three
```

如果语句包含 `{}`, `[]`, `()` 则不需要反斜杠，比如如下数组：

```python
total = ['item_one', 'item_two', 'item_three',
        'item_four', 'item_five']
```

### 同一行显示多个语句

一行使用多个语句，需要 `;` 分号分割：

```python
i: int = 100; j = 100; k:int = 100
```

#### 空行

函数之间或类的方法之间用空行分隔，表示一段新的代码的开始。类和函数入口之间也用一行空行分隔，以突出函数入口的开始。

空行与代码缩进不同，空行并不是Python语法的一部分。书写时不插入空行，Python解释器运行也不会出错。但是空行的作用在于分隔两段不同功能或含义的代码，便于日后代码的维护或重构。

记住： **空行也是程序代码的一部分**。

#### 使用import导入模块

导入整个模块 moduleA: `import moduleA`

导入模块 moduleA 的函数 funA： `from moduleA import funA`

导入模块 moduleA 的多个函数： `from moduleA import funA, funB, funC`

导入模块 moduleA 的所有函数: `from moduleA import *`

#### 控制台输出与输入函数

```python
#换行输出
print("输出")
#不换行输出，指定输出结尾为字符串空格
print("不换行输出", end=" ")
# 打印多个字符串
print ('The quick brown fox', 'jumps over', 'the lazy dog')
input("\n\n按下 enter 键后退出。") #输入
```

sys.argv 可以获取启动脚本时的输入参数，比如有如下 `HelloWorld.py`:

```python
import sys
print(sys.argv)
```

使用命令 `python HelloWorld.py name Lisi` 运行，会打印：

```
['C:/Users/Feathers/PycharmProjects/learning/HelloWorld.py', 'name', 'Lisi']
```

### 变量和数据类型

#### 变量

变量的定义和赋值：

```python
# 变量的定义
# 定义变量a，类型为int。这里会判断赋值类型，从而确定变量类型
a = 1
# 定义变量b，类型为float。使用冒号空格指定类型
b: float = 10.0
c: complex = 10

# 定义多个变量，并赋值
d, e, f = "a", 1, 1.8

# 定义多个变量并赋相同的值
g = h = i = 2
```

变量的销毁：

```python
# del var1[,var2[,var3[....,varN]]]]
del a, b, c
print(a) # NameError: name 'a' is not defined
```

**创建过程**

当我们写：a = ‘ABC’时，Python解释器干了两件事情：

1. 在内存中创建了一个’ABC’的字符串；
2. 在内存中创建了一个名为a的变量，并把它指向’ABC’。

和Java类似。

#### 标准数据类型

在python3中，公有六种标准的数据类型:

1. Number 数字
2. String 字符串
3. List 列表
4. Tuple 元组
5. Set 集合
6. Dictionary 字典

其中，Number String Tuple 是 **不可变数据**

List Dictionary Set 是 **可变数据**

**type函数：查询变量的类型**

```python
a, b, c, d = 1, 1.0, 3e5j, "str"
print(type(a), type(b), type(c), type(d))
# <class 'int'> <class 'float'> <class 'complex'> <class 'str'>
```

**instance函数：判断变量类型**

```python
print(isinstance(a, int)) // 会认为字类是一种父类类型
# True
```

**None**

用 `None` 表示。None不能理解为0，相当于其他语言中的NULL。

```python
print(type(None)) # <class 'NoneType'>
```

**Number**

* `int` 长整形
* `float` 浮点型
* `bool` 布尔类型
* `complex` 复数类型

**int**

在 python3中没有短整型，只有长整形，长整形使用int来表示。

各个进制的表示形式：

进制表示对应十进制的值转换为此进制的方式二进制0b1004bin(任意进制数)八进制0o10064oct(任意进制数)十六进制0x100256hex(任意进制数)

**float**

浮点数就是小数： `1.2`, `2.50`， `-0.58` 等

对于很小的浮点数，使用e替代10,即 `1.29e3` 就是 1290

> 整数永远是精确的 而 浮点数永远会有四舍五入的误差。
>
> 整数与浮点数运算为浮点数。

**bool**

一个布尔值只有 `True`、 `False` 两种值，在内部中使用1 和 0 存储。

所以，bool类型也是Number类型，也可以进行数值运算。

```python
print(50 + True) # 51
```

**短路运算**：布尔值可以用 `and`、 `or` 和 `not` 运算，分别对应与、或、非，并且是短路运算符。

**注意**：Python把 `0`、 `空字符串`‘和 `None` 看成 `False`，其他数值和非空字符串都看成 `True`

**String**

字符串是以 `''` 或""括起来的任意文本，比如 `'abc'`， `"xyz"` 等等。请注意， `''` 或 `""` 本身只是一种表示方式，不是字符串的一部分，因此，字符串 `'abc'` 只有a，b，c这3个字符。

* 如果字符串本身包含 `'`,比如我们要表示字符串 I’m OK ，这时，可以用" "括起来表示： `"I'm OK"`
* 类似的，如果字符串包含 `"`，我们就可以用 `' '` 括起来表示： `'Learn "Python" in imooc'`
* 如果既包含 `""`,又包含 `''`,可以使用 `\` 转义字符。

**注意**：python字符串不可变

String在Python中公有三种表现形式：

```python
s1 = '字符串1'
s2 = "字符串2"
s3 = '''字符串3
我是多行文本字符串
'''
```

**字符串截取**

字符串和java一样，是从第0个下表开始的。

```python
s = 'abcdefg'
print(s[0:3]) # abc 输出前三个字符
print(s[0:-1]) # abcdef 输出第一个到倒数第二个字符
print(s[0]) # a 输出第0个字符
print(s[1:]) # bcdefg 输出第一个字符到最后一个字符
print(s[-2:]) # fg 输出最后两个字符
```

**字符串连接操作**

```python
print (str + "TEST") # 连接字符串
```

**不转移标识**

python字符串中如果想禁用转义字符，可以使用如下方式:

```python
s = r"\测试"
print(s) # \测试
# 同样适用于 ' 和 '''
```

**其他**

```python
print (str * 2)      # 输出字符串两次
```

#### List

* List是一种有序集合，可以添加和删除其中的元素
* Python 是一种动态语言，所以List集合中的元素的类型可以不相同：例如， `[10,"Python","test",17.7]`

```
list = ['Adam', 95.5, 'Lisa', 85, 'Bart', 59] #定义一个List集合
print list # 输出该集合
 ['Adam', 95.5, 'Lisa', 85, 'Bart', 59]
```

* 空list： `list = []`
* 按照索引来访问list

  ```
  list = ['Adam', 95.5, 'Lisa', 85, 'Bart', 59]
  print list[3]  #根据索引获取元素，不可越界IndexError
  88
  ```
* 倒叙访问list，-1索引表示倒数第一个元素，-2表示倒数第二个元素，以此类推

  ```
  list = ['Adam', 95.5, 'Lisa', 85, 'Bart', 59]
  print list[-3]  #根据索引获取元素，不可越界IndexError
  88
  ```
* 向List尾部添加元素 使用 `list.append()` 方法

  ```
  list = ['Adam', 95.5, 'Lisa', 85, 'Bart', 59]
  list.append("Jack")
  print list
  ['Adam', 95.5, 'Lisa', 85, 'Bart', 59, 'Jack']
  ```
* 向List指定位置添加元素 使用 `list.insert()` 方法

  ```
  list = ['Adam', 95.5, 'Lisa', 85, 'Bart', 59]
  list.insert(0,"Jack")
  list
  ['Jack', 'Adam', 95.5, 'Lisa', 85, 'Bart', 59]
  ```
* 从list中删除元素 使用 `list.pop()` 方法，该方法返回被删除的元素

  ```
  list = ['Adam', 95.5, 'Lisa', 85, 'Bart', 59]
  list.pop() #不指定参数，默认删除尾元素
  59
  list
  ['Adam', 95.5, 'Lisa', 85, 'Bart']
  list.pop(0) #指定参数，删除指定索引处的元素
  'Adam'
  list
  [95.5, 'Lisa', 85, 'Bart']
  ```
* 替换元素

  ```
  list = ['Adam', 95.5, 'Lisa', 85, 'Bart', 59]
  list[0] = "Jack"
  list
  ['Jack', 95.5, 'Lisa', 85, 'Bart', 59]
  list[-1] = 60
  list
  ['Jack', 95.5, 'Lisa', 85, 'Bart', 60]
  ```

#### Tuple

* 元组，和List非常相似，但一旦创建了，Tuple就无法修改了

  ```
  tuple = ('Adam', 95.5, 'Lisa', 85, 'Bart', 59) #和List不同 使用了（）代替了[]
  print tuple
  ('Adam', 95.5, 'Lisa', 85, 'Bart', 59)
  print tuple[-1]
  59
  print tuple[2]
  Lisa
  ```
* 空Tuple： `tuple = ()`
* 单元素Tuple

  ```
  tuple = ("d")  #解释器默认将()解释为强制类型转换 这样代码就成了 tuple = "d"
  tuple
  'd'
  tuple = ("d",) #多加一个，避免歧义
  tuple
  ('d',)
  ```
* 可变Tuple

  ```
  tuple = ("d","dsds",["dsfds",25])
  list = tuple[-1]
  list.append("555555")
  tuple
  ('d', 'dsds', ['dsfds', 25, '555555'])
  ```

#### Dict：

\_字典，字典中的字可以根据对应的信息查到，Dict类似

一种键值对类型\_

**Dict的特点**

* Dict的查找速度与元素数量无关，查找速度快，而List会随着元素数量的增加速度也会变慢
* Dict相对于其他集合占用空间大，而List恰恰相反
* Dict是无序的打印顺序不是创建顺序，不可以用dict存储有序集合
* 他的元素key，是不可变的，字符串，浮点数，整型都可以作为dict的key
* 创建dict

  ```
  >>> d = {
  ...     'a':1,
  ...     'b':2
  ... }
  print d
  {'a': 1, 'b': 2}
  #len()函数可以用来计算集合的长度
  len(d)
  2
  ```
* 根据key获取value

  第一种 方法：

```

# 判断是否有这个key，避免KeyError
if 'b' in d:
...     print d['b']
...
2
```

第二种方法

```
#使用dict的get()方法，根据key获得value，如果不存在该key，则返回None
print d.get('d')
None
```

* 更新Dict

  ```
  d['b'] = 22
  print d
  {'a': 1, 'b': 22}
  ```
* 遍历Dict，注意，只能取到value的数值

  ```
  for key in d:
  ...     print key
  ...
  a
  b
  ```

#### Set

set的特点：

* 没有重复
* 无序性
* 内部结构和Dict类似，但是不存储value，所以查询速度也很快
* 对象不可变，可用于存储常量
* 创建Set

  调用set()方法，并传入一个List

  ```
  >>> s = set(['a','b', 'c'])
  >>> print s
  set(['a', 'c', 'b'])#该set元素无序
  ```
* 传入含有重复元素的List，会自动去除重复元素

  ```
  s = set(['a','b', 'c','a','a'])
  print s
  set(['a', 'c', 'b'])
  ```
* 访问Set

  ```
  'a' in s
  True
  'A' in s
  False
  ```
* 遍历Set

  ```
  for  x  in s:
  ...     print x
  ...
  a
  b
  ```
* 添加元素

  ```
  s.add('c')#如果add的元素在set中已经存在，则什么也不做
  print s
  set(['a', 'c', 'b'])
  ```
* 删除元素

  ```
  s.remove('a')#如果remove的元素不存在，则会报错KeyError
  print s
  set(['c', 'b'])
  ```

### 运算符

#### 算术运算符

运算符描述实例+加 – 两个对象相加a + b 输出结果 31–减 – 得到负数或是一个数减去另一个数a – b 输出结果 -11\*乘 – 两个数相乘或是返回一个被重复若干次的字符串a \* b 输出结果 210/除 – x 除以 yb / a 输出结果 2.1%取模 – 返回除法的余数b % a 输出结果 1\*\*幂 – 返回x的y次幂a\*\*b 为10的21次方//取整除 – 返回商的整数部分9//2 输出结果 4 , 9.0//2.0 输出结果 4.0

#### 比较运算符

运算符描述实例==等于 – 比较对象是否相等(a == b) 返回 False。!=不等于 – 比较两个对象是否不相等(a != b) 返回 True。>大于 – 返回x是否大于y(a > b) 返回 False。<小于 – 返回x是否小于y。所有比较运算符返回1表示真，返回0表示假。这分别与特殊的变量True和False等价。注意，这些变量名的大写。(a < b) 返回 True。>=大于等于 – 返回x是否大于等于y。(a >= b) 返回 False。<=小于等于 – 返回x是否小于等于y。(a <= b) 返回 True。

#### 赋值运算符

运算符描述实例=简单的赋值运算符c = a + b 将 a + b 的运算结果赋值为 c+=加法赋值运算符c += a 等效于 c = c + a-=减法赋值运算符c -= a 等效于 c = c – a\*=乘法赋值运算符c *= a 等效于 c = c* a/=除法赋值运算符c /= a 等效于 c = c / a%=取模赋值运算符c %= a 等效于 c = c % a\*\*=幂赋值运算符c **= a 等效于 c = c** a//=取整除赋值运算符c //= a 等效于 c = c // a

#### 位运算符

运算符描述实例&按位与运算符：参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0(a & b) 输出结果 12 ，二进制解释： 0000 1100|按位或运算符：只要对应的二个二进位有一个为1时，结果位就为1。(a | b) 输出结果 61 ，二进制解释： 0011 1101^按位异或运算符：当两对应的二进位相异时，结果为1(a ^ b) 输出结果 49 ，二进制解释： 0011 0001\~按位取反运算符：对数据的每个二进制位取反,即把1变为0,把0变为1。\~x类似于 -x-1(\~a ) 输出结果 -61 ，二进制解释： 1100 0011， 在一个有符号二进制数的补码形式。<<左移动运算符：运算数的各二进位全部左移若干位，由"<<"右边的数指定移动的位数，高位丢弃，低位补0。a << 2 输出结果 240 ，二进制解释： 1111 0000>>右移动运算符：把">>"左边的运算数的各二进位全部右移若干位，">>"右边的数指定移动的位数a >> 2 输出结果 15 ，二进制解释： 0000 1111

#### 逻辑运算符（短路）

运算符逻辑表达式描述实例andx and y布尔"与" – 如果 x 为 False，x and y 返回 False，否则它返回 y 的计算值。(a and b) 返回 20。orx or y布尔"或" – 如果 x 是 True，它返回 x 的值，否则它返回 y 的计算值。(a or b) 返回 10。notnot x布尔"非" – 如果 x 为 True，返回 False 。如果 x 为 False，它返回 True。not(a and b) 返回 False

#### 成员运算符

运算符描述实例in如果在指定的序列中找到值返回 True，否则返回 False。x 在 y 序列中 , 如果 x 在 y 序列中返回 True。not in如果在指定的序列中没有找到值返回 True，否则返回 False。x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。

#### 身份运算符

运算符描述实例isis 是判断两个标识符是不是引用自一个对象**x is y**, 类似 **id(x) == id(y)** , 如果引用的是同一个对象则返回 True，否则返回 Falseis notis not 是判断两个标识符是不是引用自不同对象**x is not y** ， 类似 **id(a) != id(b)**。如果引用的不是同一个对象则返回结果 True，否则返回 False。

> is 比较引用的地址，==比较值。

#### 运算符优先级

运算符描述\*\*指数 (最高优先级)\~ + –按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@)\\\* / % //乘，除，取模和取整除+ –加法减法>> <<右移，左移运算符&位 ‘AND’^ |位运算符<= < > >=比较运算符<> == !=等于运算符= %= /= //= -= += \*= \*\*=赋值运算符is is not身份运算符in not in成员运算符and or not逻辑运算符

### 条件判断和循环

#### Python 代码缩进规则

* 具有相同缩进的行代码，将被视作一个代码块。

#### if 条件语句

```
>>> if score == 100:
...     print "you score is very good"
... elif score > 80:
...     print "you score is good",score
... else:
...     print "not good"
...
you score is good 85
```

#### for循环语句

```
list = ['Adam', 95.5, 'Lisa', 85, 'Bart', 59]
>>> for child in list:  #child的含义：依次取出list中的元素并赋值给child，让child做出处理（在缩进的代码块中）
...     print child
...
Adam
95.5
Lisa
85
Bart
59
```

遍历tuple类似。

#### while循环

```
n = 10
x = 1
while x < n:
       print x
        x = x+1
```

拥有break和continue。

#### 支持多重循环

```
for x in ['a','b','c']:
...     for y in ['1','2','3']:
...             print x + y
```

输出结果为

a1、a2、a3、b1、b2、b3、c1、c2、c3

### 函数

#### 查看帮助信息

* 官方文档地址：[行内式链接](http://example.com/)
* 使用 `help(abs)` 查看abs函数的帮助信息

#### 定义一个函数

```
def my_abs(x):
...     if x >= 0:
...             return x
...     else:
...             return -x
```

注意：return None 等同于 return 等同于 无return语句

#### 函数返回多值，比如坐标的x,y,z

**数学函数**:

abs(x) 绝对值函数

type(x) 类型函数

round(x) 四舍五入函数

**内建函数**

使用dir( *builtins*) 函数查看python中的内建函数

使用help(abs) 查看内建函数abs的信息(非内建函数无法使用此命令)

**模块**

类似于头文件

使用import math 导入math模块,使用math下的函数

一个完整的python文件就是一个模块,math模块的文件就是math.py

导入多个模块,模块间用逗号分开

导入指定的模块属性:from Module1 import ModuleElement

**包package**

一个层次文件的目录结构

比如:import AAA.CCC.c1导入AAA的子包BBB下的c1模块 或者 : from AAA.CCC.c1 import funct() 直接导入函数
