# 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() 直接导入函数


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yangsx95.gitbook.io/notes/programming-language/python.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
