编译
Python程序运行时不需要编译成二进制代码,而直接从源码运行程序,简单来说是,Python解释器将源码转换为字节码,然后再由解释器来执行这些字节码。解释器的具体工作:
1、完成模块的加载和链接;
2、将源代码编译为PyCodeObject对象(即字节码),写入内存中,供CPU读取;
3、从内存中读取并执行,结束后将PyCodeObject写回硬盘当中,也就是复制到.pyc或.pyo文件中,以保存当前目录下所有脚本的字节码文件。
__pycache__文件夹
__pycache__文件夹的意义何在呢?
因为第一次执行代码的时候,Python解释器已经把编译的字节码放在__pycache__文件夹中,这样以后再次运行的话,如果被调用的模块未发生改变,那就直接跳过编译这一步,直接去__pycache__文件夹中去运行相关的 *.pyc 文件,大大缩短了项目运行前的准备时间
关键字
| 类别 | 关键字 | 说明 |
|---|---|---|
| 逻辑值 | True | 布尔真值 |
False | 布尔假值 | |
None | 表示空值或无值 | |
| 逻辑运算 | and | 逻辑与运算 |
or | 逻辑或运算 | |
not | 逻辑非运算 | |
| 条件控制 | if | 条件判断语句 |
elif | 否则如果(else if 的缩写) | |
else | 否则分支 | |
| 循环控制 | for | 迭代循环 |
while | 条件循环 | |
break | 跳出循环 | |
continue | 跳过当前循环的剩余部分,进入下一次迭代 | |
| 异常处理 | try | 尝试执行代码块 |
except | 捕获异常 | |
finally | 无论是否发生异常都会执行的代码块 | |
raise | 抛出异常 | |
| 函数定义 | def | 定义函数 |
return | 从函数返回值 | |
lambda | 创建匿名函数 | |
| 类与对象 | class | 定义类 |
del | 删除对象引用 | |
| 模块导入 | import | 导入模块 |
from | 从模块导入特定部分 | |
as | 为导入的模块或对象创建别名 | |
| 作用域 | global | 声明全局变量 |
nonlocal | 声明非局部变量(用于嵌套函数) | |
| 异步编程 | async | 声明异步函数 |
await | 等待异步操作完成 | |
| 其他 | assert | 断言,用于测试条件是否为真 |
in | 检查成员关系 | |
is | 检查对象身份(是否是同一个对象) | |
pass | 空语句,用于占位 | |
with | 上下文管理器,用于资源管理 | |
yield | 从生成器函数返回值 |
数据类型
Python3 中常见的数据类型有:
- Number(数字)— Python3 支持 int、float、bool、complex(复数)
>>> a, b, c, d = 20, 5.5, True, 4+3j >>> print(type(a), type(b), type(c), type(d)) <class 'int'> <class 'float'> <class 'bool'> <class 'complex'> - String(字符串)— Python中的字符串用单引号 ' 或双引号 " 括起来,同时使用反斜杠 \ 转义特殊字符。
- List(列表)— [ ] 列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。
#!/usr/bin/python3 list = [ 'abcd', 786 , 2.23, 'runoob', 70.2 ] # 定义一个列表 tinylist = [123, 'runoob'] print (list) # 打印整个列表 print (list[0]) # 打印列表的第一个元素 print (list[1:3]) # 打印列表第二到第四个元素(不包含第四个元素) print (list[2:]) # 打印列表从第三个元素开始到末尾 print (tinylist * 2) # 打印tinylist列表两次 print (list + tinylist) # 打印两个列表拼接在一起的结果 - Tuple(元组)— ( ) 元组与列表类似,不同之处在于元组的元素不能修改。元组写在小括号 () 里,元素之间用逗号隔开。
#!/usr/bin/python3 tuple = ( 'abcd', 786 , 2.23, 'runoob', 70.2 ) tinytuple = (123, 'runoob') print (tuple) # 输出完整元组 print (tuple[0]) # 输出元组的第一个元素 print (tuple[1:3]) # 输出从第二个元素开始到第三个元素 print (tuple[2:]) # 输出从第三个元素开始的所有元素 print (tinytuple * 2) # 输出两次元组 print (tuple + tinytuple) # 连接元组 - Set(集合)— { } Python 中的集合是一种无序、可变的数据类型,用于存储唯一的元素。集合中的元素不会重复,并且可以进行交集、并集、差集等常见的集合操作。在 Python 中,集合使用大括号 {} 表示,元素之间用逗号 , 分隔。
另外,也可以使用 set() 函数创建集合。
#!/usr/bin/python3 sites = {'Google', 'Taobao', 'Runoob', 'Facebook', 'Zhihu', 'Baidu'} print(sites) # 输出集合,重复的元素被自动去掉 # 成员测试 if 'Runoob' in sites : print('Runoob 在集合中') else : print('Runoob 不在集合中') # set可以进行集合运算 a = set('abracadabra') b = set('alacazam') print(a) print(a - b) # a 和 b 的差集 print(a | b) # a 和 b 的并集 print(a & b) # a 和 b 的交集 print(a ^ b) # a 和 b 中不同时存在的元素 - Dictionary(字典)— { } 列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。
Python3 的六个标准数据类型中:
- 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
- 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。
| 类型 | + | - | * | / | // | % | ** | & | | | ^ | 说明 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 数值(int/float/complex) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | × | × | × | 常规算数运算 |
| 列表(list) | ✔(拼接) | × | ✔(重复) | × | × | × | × | × | × | × | +/* 用于序列操作,不是数值 |
| 元组(tuple) | ✔(拼接) | × | ✔(重复) | × | × | × | × | × | × | × | 与列表类似,但不可变 |
| 集合(set/frozenset) | × | ✔(差集) | × | × | × | × | × | ✔(交集) | ✔(并集) | ✔(对称差) | 运算符用于集合关系操作 |
| 字典(dict,Python 3.9+) | ✔(合并) | × | × | × | × | × | × | × | ✔(合并) | × | 合并/更新 key/value,旧字典值可被覆盖 |
字符串
Python 可以使用引号( ' )、双引号( " )、三引号( ''' 或 """ ) 来表示字符串,引号的开始与结束必须是相同类型的。
其中三引号可以由多行组成,编写多行文本的快捷语法,常用于文档字符串,在文件的特定地点,被当做注释。
Python 不支持单字符类型,单字符在 Python 中也是作为一个字符串使用。
Python 访问子字符串,可以使用方括号 [] 来截取字符串,字符串的截取的语法格式如下:
变量[头下标:尾下标]
print str # 输出完整字符串
print str[0] # 输出字符串中的第一个字符
print str[2:5] # 输出字符串中第三个至第六个之间的字符串
print str[2:] # 输出从第三个字符开始的字符串
print str * 2 # 输出字符串两次
print str + "TEST" # 输出连接的字符串
print str[2:5:2] #输出字符串中第二个到第五个字符且步进为2 1. f'' 或 f"":格式化字符串 (f-strings)
f'' 是一种格式化字符串的方式,可以在字符串中嵌入表达式,表达式会在运行时被解析并替换。
name = "Alice"
age = 25
greeting = f"Hello, my name is {name} and I am {age} years old."
print(greeting) # 输出: Hello, my name is Alice and I am 25 years old. 2. r'' 或 r"":原始字符串 (raw strings)
r'' 用于定义原始字符串,表示忽略字符串中的转义字符(如 \n、\t 等),常用于正则表达式或文件路径。
path = r"C:\Users\Name\Documents" # 不需要对 \ 转义
print(path) # 输出: C:\Users\Name\Documents
import re
pattern = r"\d+" # 匹配一个或多个数字
result = re.findall(pattern, "There are 123 apples.") # 输出: ['123'] 3. b'' 或 b"":字节字符串 (byte strings)
b'' 表示字节序列,用于处理二进制数据(如文件、网络通信等)。字符串会被编码为字节序列,通常使用 utf-8 编码。
data = b"Hello"
print(data) # 输出: b'Hello'
# 将字符串转换为字节
text = "Hello"
binary_data = text.encode('utf-8')
print(binary_data) # 输出: b'Hello' - 这是一个字节序列,表示
Hello的每个字符使用其 ASCII 编码表示的字节。 - 它的类型是
bytes,而不是普通的字符串类型str。 -
b'Hello'的实际存储为[72, 101, 108, 108, 111](即字符H,e,l,l,o对应的 ASCII 码值)。 - 当直接打印时,显示
b'Hello',以区分它与普通字符串。 -
encode('utf-8')将字符串类型转换为字节类型。utf-8是一种常用的字符编码方式,用于表示 Unicode 字符。 - 这里,
"Hello"是普通字符串(str),encode转为字节串,与b"Hello"的结果一致。
4. u'':Unicode字符串
u'' 是 Python 2 的特性,表示 Unicode 字符串。在 Python 3 中,所有字符串默认就是 Unicode 类型,因此通常不需要这个前缀。
常见转义字符
| 转义字符 | 含义 |
\\ | 反斜杠本身 |
\' | 单引号 |
\" | 双引号 |
\n | 换行符 |
\t | 水平制表符(Tab) |
\r | 回车符 |
\b | 退格符 |
\f | 换页符 |
\v | 垂直制表符 |
\a | 响铃(警报) |
\0 | 空字符(Null) |
\xhh | 十六进制值表示的字符,例如 \x41 表示 A |
\ooo | 八进制值表示的字符,例如 \101 表示 A |
\uXXXX | 16 位 Unicode 字符,例如 \u4F60 表示中文“你” |
\UXXXXXXXX | 32 位 Unicode 字符,例如 \U0001F600 表示表情符号 😀 |
列表List
[ ]支持字符,数字,字符串甚至可以包含列表(即嵌套)
特点:
- 有序的,可变的容器。
- 可以存储任意类型的对象。
- 支持重复元素。
常见操作:
- 通过索引访问或修改元素。
- 使用
append添加元素,remove删除元素。
def append(self, p_object):给list里面追加一个元素
def extend(self, iterable):将一个可迭代对象,按照单个元素追加的模式,一个个追加入原list
def insert(self, index, p_object):插入一个元素,需要指定插入的index
def pop(self, index=None):删除指定index的元素,默认删除最后一个
def remove(self, value):删除列表里面的对象,需要指定对象,list里面对象重复只删除第一个
del list[index]:删除一个元素,需要指定插入的index
def reverse(self):将列表里面的元素倒叙
def sort(self, cmp=None, key=None, reverse=False):将列表里面的与元素升序排列
def count(self, value)::统计列表里面元素的值,相同元素的个数
def index(self, value, start=None, stop=None)::根据值找索引,可以指定起始和终止位置
元组Tuple
元组不能二次赋值,相当于只读列表。
用 () 标识,内部元素用逗号隔开。但是元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运算符使用
特点:
- 有序的、不可变的容器。
- 适用于需要存储固定数据的场景。
- 可以存储任意类型的对象。
常见操作:
- 元组一旦定义,其内容不可修改。
- 可以使用索引访问元素。
调用元组中的元素时也是通过xxx[’yy’]
#!/usr/bin/python
tup1 = ('physics', 'chemistry', 1997, 2000)
tup2 = (1, 2, 3, 4, 5, 6, 7 )
print "tup1[0]: ", tup1[0]
print "tup2[1:5]: ", tup2[1:5]
字典Dictionary
字典(dictionary)是除列表以外python之中最灵活的内置数据结构类型。列表是有序的对象集合,字典是无序的对象集合。
两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。
字典用"{ }"标识。字典由索引(key)和它对应的值value组成。
字典的每个键值key=>value对用冒号 :分割,每个对之间用逗号,分割,整个字典包括在花括号{}中 ,格式如下所示:
d = {key1 : value1, key2 : value2, key3 : value3 }
键必须是唯一的,但值则不必。
值可以取任何数据类型,但键必须是不可变的,如字符串,数字。
调用字典中的某一个元素为xxx[‘yy’]
#!/usr/bin/python
tinydict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
print "tinydict['Name']: ", tinydict['Name']
print "tinydict['Age']: ", tinydict['Age']
集合
集合(set)是一个无序的不重复元素序列。
可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
特点:
- 无序、不可重复的元素集合。
- 适用于需要去重或集合运算的场景。
- 集合中的元素必须是可哈希的(通常为不可变数据类型,如字符串或数值)。
常见操作:
- 添加元素:
add。 - 去重、集合运算:如
union(并集)、intersection(交集)。
创建格式:
parame = {value01,value02,...}
或者
set(value)
包、模块
多个关系密切的模块应该组织成一个包,以便于维护和使用。这项技术能有效避免名字空间冲突。创建一个名字为包名字的文件夹并在该文件夹下创建一个__init__.py 文件就定义了一个包。你可以根据需要在该文件夹下存放资源文件、已编译扩展及子包。
一个模块是一个可以包含Python定义和可执行语句的文件,文件的名字就是模块名加上.py扩展名。 通常模块为一个文件,直接使用import来导入就好了。可以作为module的文件类型有".py"、".pyo"、".pyc"、".pyd"、".so"、".dll"。
from 、import:
1、使用import导入模块 :( 最后一个item可以是一个模块或包,但不能是类、函数和变量 )
import 模块
import 包.模块
2、使用from + import来导入包中的部分模块:
from PackageA.SubPackageA import ModuleA 可以直接使用模块名而不用加上包前缀
from PackageA.SubPackageA import * 导入包下的所有模块
from PackageA.SubPackageA.ModuleA import functionA 也可以直接导入模块中的函数或变量
virtualenv
创建一个独立的Python运行环境,命名为venv
virtualenv --no-site-packages venv
参数--no-site-packages :已经安装到系统Python环境中的所有第三方包都不会复制过来
进入环境venv
source venv/bin/activate
离开环境venv
deactivate
$PYTHONPATH为当前环境查找python执行文件的路径
Python中的各种符号
总结如下:
| 运算符 | 描述 | 实例 |
| 算术运算符 | ||
| + | 加 - 两个对象相加 | a + b 输出结果 30 |
| - | 减 - 得到负数或是一个数减去另一个数 | a - b 输出结果 -10 |
| * | 乘 - 两个数相乘或是返回一个被重复若干次的字符串 | a * b 输出结果 200 |
| / | 除 - x除以y | b / a 输出结果 2 |
| % | 取模 - 返回除法的余数 | b % a 输出结果 0 |
| ** | 幂 - 返回x的y次幂 | a**b 为10的20次方, 输出结果 100000000000000000000 |
| // | 取整除 - 返回商的整数部分(向下取整) | >>> 9//24>>> -9//2-5 |
| 比较运算符 | ||
| == | 等于 - 比较对象是否相等 | (a == b) 返回 False。 |
| != | 不等于 - 比较两个对象是否不相等 | (a != b) 返回 true. |
| <> | 不等于 - 比较两个对象是否不相等 | (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 |
| 逻辑运算符 | ||
| and | 布尔"与" - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。 | (a and b) 返回 20。 |
| or | 布尔"或" - 如果 x 是非 0,它返回 x 的值,否则它返回 y 的计算值。 | (a or b) 返回 10。 |
| not | 布尔"非" - 如果 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。 |
| 身份运算符 | ||
| is | is 是判断两个标识符是不是引用自一个对象 | x is y, 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False |
| is not | is not 是判断两个标识符是不是引用自不同对象 | x is not y , 类似 id(a) != id(b)。如果引用的不是同一个对象则返回结果 True,否则返回 False。 |
| 其他符合 | ||
| . | 层级调用 | |
| # | 单行注释 | |
| “”“ ”“” 或‘’‘ ’‘’ | 多行注释 | |
| ‘ | 单引号 | |
| “ | 双引号 | |
| \ | 转义 / 续行符(折行)/ 反斜杠 | |
| ( ) | 函数方法/类/元组 | |
| [] | 列表 | |
| {} | 字典 | |
| , | 分隔符 | |
| @ | Decorator装饰器 | |
| : | 类/方法体 | |
| -> | python函数定义的函数名后面,为函数添加元数据,描述函数的返回类型,从而方便开发人员使用 | |
| >>> | python控制台命令输入提示符 |
| := | 赋值表达式 | 主要两种用法: 用法一:简单理解,在语句中对中间变量赋值,让代码更简洁,提高运算速度,网上例子很多 if (match := pattern.match(data)) is not None: print(match.group(0)) 用法二:简化列表推导式(个人理解其实还是用的用法一) [y for x in names if (y := f(x))] |
Python发行版
在选择Python语言进行软件开发时,我们面对的实际是一套大型语言生态系统——其中包含各类涵盖无数编程需求的软件包。但除了从GUI开发到机器学习的各类库之外,各位还能够从多种Python运行时中作出选择——其中部分运行时也许更适合您当前的用例条件。
下面,我们将简单介绍目前最常用的几款Python发行版——从标准实现(CPython)到针对速度进行优化的版本(PyPy),再到特殊用例(Anaconda、ActivePython)乃至最初为完全不同的其他语言设计的运行时(Jython、IronPython)。
目录
CPython
Anaconda Python
ActivePython
PyPy
Jython
一、CPython
CPython属于Python参考实现方案,可算是所有其他Python衍生发行版的一套标准化版本。CPython利用C语言编写而成,而其编写者包含多位Python语言顶级决策层中的核心人员。
1.CPython用例
CPython属于Python的参考实现版本,因为其在优化方面表现得最为保守。当然,这并不是缺点,而是设计取向。Python的维护者们希望将CPython打造为Python最具广泛兼容性与标准化的实现方案。
CPython最适合对Python标准的兼容性与一致性要求较高的用户。此外,CPython同样适用于希望以最基本方式使用Python并愿意为此放弃某些便捷性的专业人士。
举例来说,您需要进行些许调整才能利用CPython设置虚拟环境。而其他发行版(Anaconda)则在工作区设置中提供更多自动化功能。
2.CPython的局限性
CPython并不像Python的其他版本那样对性能作出深度优化。其不提供原生JIT(即时)编译器,不提供加速数学库,也没有用于提升性能的第三方附加选项。
您当然可以根据需求自行添加,但其并不直接提供绑定包。当然,这一切都是设计取向所决定,旨在确保CPython作为一套参考实现版本能够最大程度实现兼容性与标准化。而性能优化——开发人员可以选择其他配合工具包进行添加。
此外,CPython仅提供一组用于使用Python的基准性工具。举例来说,pip软件包管理器会从Python原生PyPI软件包库当中获取并安装各软件包。如果开发者允许,Pip甚至可以安装经过预编译的二进制文件(通过轮盘发布格式),但无法安装PyPI所不包含的任何其他软件包依赖项。
二、Anaconda Python
Anaconda源自Anaconda公司之手(原名为Continuum Analytics),其设计目标在于服务那些需要由商业供应商提供支持且具备企业支持服务的Python开发者。Anaconda Python的主要用例包括数学、统计学、工程、数据分析、机器学习以及其他相关应用。
1.Anaconda Python用例
Anaconda捆绑有Python商业与科学使用场景当中的各类常用库——包括SciPy、NumPy以及Numba等等,同时通过一套定制化软件包管理系统提供更多库访问能力。
Anaconda最为出色的特性在于将上述元素进行了高效组合。在安装之后,Anaconda提供桌面应用程序Anaconda Navigator,可通过方便的GUI帮助用户使用Anaconda环境中的各类功能。相较于CPython,Anaconda当中的组件搜索、更新以及使用流程都更为简便。
其另一大优势,在于Anaconda能够根据特定软件包的需求处理Python生态系统之外的组件。其中专门为Anaconda打造的conda软件包管理器能够根据外部软件要求安装Python以及第三方软件包。
2.Anaconda Python的局限性
由于Anaconda当中包含大量实用性库,且只需要简单操作即可安装更多库,因此Anaconda的安装体积往往要比CPython大得多。基本CPython安装运行大约需要100 MB空间,而Anaconda则会很快增长至GB级别。如果您的资源有限,那么这有可能产生问题。
帮助Anaconda瘦身的方法之一在于安装Miniconda,这是一套精简版本的Anaconda,其中只包含启动与运行所必需的部分。如果必要,您可以将软件包添加到Miniconda当中,并关注各软件包具体要消耗多少空间。
三、ActivePython
与Anaconda类似,ActivePython同样由营利性企业创建及维护——ActiveState公司。该公司还在销售多种语言运行时以及多语言Komodo IDE。
1.ActivePython用例
ActivePython主要面向企业用户与数据科学家——即希望使用Python语言,但又不愿把大量精力浪费在Python的组装与管理方面。ActivePython使用Python中的常规pip软件包管理器,但同时亦以认证压缩包的形式提供数百套通用库,外加英特尔数学核心库等其他一些具有第三方依赖关系的公共库。
2.ActivePython的局限性
ActivePython对软件包外部依赖关系的处理方式存在一大潜在缺点。如果大家希望将现有项目(例如TensorFlow)升级至具有复杂依赖关系的较新版本,则需要同时升级ActivePython。如果开发工作在与特定版本的项目相关联的环境中进行,那么这并不会造成影响。但目前的开发工作往往需要紧跟前沿版本的发布,在这种情况下大家往往会遇到很多麻烦。
四、PyPy
PyPy 属于CPython解释器的替代品,其利用即时(JIT)编译以加速Python程序的执行。根据实际执行的任务情况,其性能提升可能非常显著。
1.PyPy用例
人们对于Python——特别是CPython的抱怨之声,主要围绕其速度表现展开。在默认情况下,Python的运行速度远不及C语言——差距甚至可能达到数百倍。PyPy JIT将Python代码编译为机器语言,从而带来平均7.7倍于CPython的运行速度。在某些特定任务中,其提速效果能够达到50倍。
更重要的是,开发人员能够较为轻松地享受到这些便利。将CPython换成PyPy,您就基本完成了提速工作。
2.PyPy的局限性
PyPy一般更适用于处理“纯”Python应用程序。由于PyPy会模拟CPYthon的原生二进制接口,因此在处理NumPy等包含C库接口的Python软件包时,其表现并不理想。不过随着时间推移,PyPy的开发者们已经逐步解决了这个问题,并使得PyPy能够更好地同依赖于C扩展的Python软件包进行兼容。但必须承认,虽然已经有所改善,PyPy对C扩展的支持仍然有限。
PyPy的另一大短板在于运行时大小。Windows上的核心CPython运行时——不包含标准库——约为4 MB,而PyPy运行时则在32 MB左右。同样需要注意的是,PyPy还长期立足Python的2.x分支,例如目前面向Python 3.x版本的PyPy目前只在32位Windows系统上提供beta测试版本。(PyPy已经在Linux与MacOS上提供同时面向Python 2x与3.x的64位版本。)
五、Jython
JVM(Java虚拟机)能够作为除Java之外的多种语言的运行时选项。这份长的名单包括Groovy、Scala、Clojure、Kotlin、Python以及——没错,当然还有Jython 。
1.Jython用例
Jython项目能够将Python 2.x编译为JVM字节码,并在JVM上运行生成的程序。在某些情况下,Jython编译的程序在运行速度上甚至高于CPython编译程序——但并非始终如此。
Jython提供的最大优势在于能够与Java生态系统中的其他部分直接进行互操作。Java的使用范围比Python更为广泛。通过在JVM上运行Python,开发人员将能够享受并非为Python开发的庞大库与框架生态系统。同样,Jython亦允许Java开发人员使用Python库。
2.Jython的局限性
Jython最大的弊端在于其仅支持Python的2.x版本。目前对Python 3.x版本的支持能力尚在开发当中,但仍需要相当一段时间。当下,还没有任何相关版本放出。
同样需要注意的是,虽然Jython能够将Python引入JVM,但却无法将Python引入Android。由于Jython目前不具备适用于Android的端口,因此Jython不能用于开发Andoird应用。
六、IronPython
类似于Jython的JVM上Python实现方案定位,IronPython属于一套立足.Net运行时——或者CLR(公共语言运行时)——的Python实现方案。IronPython利用CLR的DLR(动态语言运行时)以允许Python程序以等同于CPython的动态水平实现运行。
1.IronPython 用例
与Jython类似,IronPython同样属于一种桥梁。其最主要的用例在于实现Python与.Net间的互操作性。现有.Net程序集能够利用Python的本地导入与对象操作语法在IronPython程序中实现加载。
此外,我们也可以将IronPython代码编译成程序集,并直接运行或者接受其他语言的调用。但需要注意的是,其中的MSIL(微软中间语言)无法直接由其他.Net语言进行访问,因为其并不支持公共语言规范。
2.IronPython的局限性
与Jython类似,IronPython目前只支持Python 2.x版本。不过IronPython 3.x实现方案已经处于紧锣密鼓的开发当中。
基本函数
类型转换函数
| 函数 | 功能 |
|---|---|
int(x[, base]) | 将 x 转换为整数,可指定进制 |
float(x) | 将 x 转换为浮点数 |
str(x) | 将 x 转换为字符串 |
bool(x) | 将 x 转换为布尔值 |
list(x) | 将可迭代对象转换为列表 |
tuple(x) | 将可迭代对象转换为元组 |
set(x) | 将可迭代对象转换为集合 |
dict(x) | 将键值对序列转换为字典 |
chr(x) | 将整数转换为 Unicode 字符 |
ord(x) | 将字符转换为整数 Unicode 编码 |
hex(x) | 将整数转换为十六进制字符串 |
oct(x) | 将整数转换为八进制字符串 |
bin(x) | 将整数转换为二进制字符串 |
数学相关函数
| 函数 | 功能 |
|---|---|
abs(x) | 绝对值 |
round(x[, n]) | 四舍五入到 n 位小数 |
pow(x, y[, z]) | 幂运算,可取模 |
divmod(a, b) | 返回 (a//b, a%b) |
max(iterable / args) | 返回最大值 |
min(iterable / args) | 返回最小值 |
sum(iterable[, start]) | 求和 |
all(iterable) | 所有元素为 True 返回 True |
any(iterable) | 有一个元素为 True 返回 True |
序列操作相关函数
| 函数 | 功能 |
|---|---|
len(obj) | 长度或元素个数 |
range(start, stop[, step]) | 生成整数序列 |
enumerate(iterable[, start]) | 返回索引和值的迭代器 |
zip(*iterables) | 多个可迭代对象压缩成元组迭代器 |
reversed(seq) | 反转迭代器 |
sorted(iterable[, key][, reverse]) | 返回排序后的新列表 |
list.sort() | 就地排序 |
sum(iterable) | 求和 |
字符串相关函数
| 函数 / 方法 | 功能 |
|---|---|
len(s) | 字符串长度 |
ord(c) / chr(i) | 字符 ↔ Unicode 整数 |
str.upper() / str.lower() | 大小写转换 |
str.strip() | 去除首尾空格 |
str.replace(old, new) | 字符串替换 |
str.split(sep=None) | 分割成列表 |
str.join(iterable) | 列表拼接成字符串 |
str.find(sub) | 查找子串索引,找不到返回 -1 |
str.startswith(prefix) / str.endswith(suffix) | 前缀/后缀判断 |
str.isdigit() / str.isalpha() / str.isalnum() | 类型判断 |
文件操作相关函数
| 函数 / 方法 | 功能 |
|---|---|
open(filename, mode) | 打开文件 |
file.read(size=-1) | 读取文件 |
file.readline() | 读取一行 |
file.readlines() | 读取所有行,返回列表 |
file.write(str) | 写入文件 |
file.writelines(list_of_str) | 写入多行 |
file.close() | 关闭文件 |
with open(...) as f: | 上下文管理,自动关闭文件 |
其他常用函数
| 函数 | 功能 |
|---|---|
type(obj) | 返回对象类型 |
isinstance(obj, cls) | 判断对象类型 |
id(obj) | 返回对象唯一标识(内存地址) |
dir(obj) | 返回对象属性列表 |
help(obj) | 查看对象帮助文档 |
eval(expr) | 执行字符串表达式并返回结果 |
exec(code) | 执行代码字符串 |
globals() / locals() | 返回全局 / 局部变量字典 |
callable(obj) | 判断对象是否可调用 |