Python
编程范型 | 多范型:过程式、结构化、模块化、反射式、面向对象、函数式 |
---|---|
設計者 | 吉多·范罗苏姆 |
實作者 | Python软件基金会 |
发行时间 | 1991年[1] |
当前版本 | |
型態系統 | 鸭子类型[7]、动态、强类型[8]、渐进(自从3.5)[9] |
操作系统 | 跨平臺 |
許可證 | Python软件基金会许可证 |
文件扩展名 | .py、.pyi、.pyc、.pyd、.pyo(3.5之前)[10]、.pyw、.pyz(自从3.5)[11] |
網站 | www |
主要實作產品 | |
CPython、PyPy、Stackless Python、MicroPython、CircuitPython、IronPython、Jython | |
衍生副語言 | |
Cython、RPython | |
啟發語言 | |
ABC[12]、ALGOL 68[13]、APL[14]、C[15]、C++[16]、CLU[17]、Dylan[18]、Haskell[19]、Icon[20]、Java[21]、Lisp[22]、Modula-3[16]、Perl[23]、Standard ML[14] | |
影響語言 | |
Boo、Cobra、CoffeeScript[24]、D、F#、GDScript[25]、Genie[26]、Go[27]、Groovy、JavaScript[28][29]、Julia[30]、Mojo[31]、Nim、Ruby[32]、Starlark[33]、Swift[34] | |
Python(英式發音:/ˈpaɪθən/;美式發音:/ˈpaɪθɑːn/),是一种广泛使用的解释型、高级和通用的编程语言。Python支持多种编程范型,包括结构化、过程式、反射式、面向对象和函数式编程。它拥有动态类型系统和垃圾回收功能,能够自动管理内存使用,并且其本身拥有一个巨大而广泛的标准库。它的语言结构以及面向对象的方法,旨在帮助程序员为小型的和大型的项目编写逻辑清晰的代码。
吉多·范罗苏姆于1980年代后期开始研发Python,作为ABC语言的后继者[20],它也可以被视为采用了叫做M-表达式的中缀表示法的一种LISP方言[35]。吉多·范罗苏姆于1991年首次发布 Python 0.9.0[36]。Python 2.0于2000 年发布并引入了新功能。Python 3.0于2008年发布,它是该语言的主要修订版,并非完全向后兼容。Python 2于2020年随2.7.18版停止支持[37]。
Python的设计哲学,强调代码的可读性和简洁的语法,尤其是使用空格缩进来划分代码块。相比於C语言或Java,Python让开发者能够用更少的代码表达想法。
Python解释器本身几乎可以在所有的操作系统中运行,它的官方直譯器CPython是用C语言编写的。Python是一個由社群驱动的自由软件,目前由Python软件基金会管理。Python是最受欢迎的编程语言之一[38][39][40][41]。
歷史
[编辑]Python的創始人吉多·范羅蘇姆,在1982年至1995年间,参与了荷兰数学和计算机科学研究学会多个项目的工作[42]。1989年的聖誕節期間,他決心開發一個新的腳本解釋程式,作為ABC語言的繼承者,并且用它替代Unix shell和C语言来进行系统管理[20],担负与Amoeba操作系统[43]之间的交互操作并进行例外处理[12]。他是BBC電視劇《Monty Python的飛行馬戲團》的爱好者,所以选取了Python作为这个编程语言的名字[44]。范羅蘇姆作为Python的主要開發者,独自担负这个项目的发展决策者职责,直到2018年7月12日,他宣布从終身仁慈獨裁者(BDFL)的职位上“永久休假”[45][46]。他在2019年1月至11月参与了第一届五人掌控委员会继续领导项目发展[47][48]。
在1991年2月,范羅蘇姆在alt.sources上发布了最初代码(标记为版本0.9.0)[1],这时就已经存在了带继承的类、例外处理、函数和核心类型list
、dict
、str
等。在这个最初发行中就有了从Modula-3引进的模块系统[49],和例外处理机制[12]。在1994年1月,Python达到了版本1.0[50],其主要新特征是由Amrit Prem提供的函数式编程工具lambda
、map
、filter
和reduce
[51]。受Modula-3启发,Python 1.1介入了缺省参数值,Python 1.3介入了关键字参数。Python 1.4介入了对复数的内建支持,还包含了采取名字修饰的一种基本形式的数据隐藏[52]。
在2000年10月,Python 2.0發布,它从函数式编程语言Haskell中引进了列表推导式,并且支持了Unicode,还向垃圾回收系统增加了环检测算法[53]。Python 2.1支持了静态嵌套作用域和闭包[54]。Python 2.2进行了重大革新,将Python中用C语言写成的类型,和用Python语言写成的类,统一成在同一个层级中,使得Python的对象模型成为纯粹而一致的对象模型[55];还介入了迭代器[56],受CLU和Icon启发的生成器[57],和描述器协议[58]。Python 2.3介入了从Dylan引进的方法决定次序[18]。Python 2.4介入了集合类型,和函数修饰器[59]。Python 2.5介入了with
语句[60],并在官方实现中介入了抽象语法树[61]。
在2008年12月,Python 3.0發布,它对语言做了较大修订而不能完全后向兼容[62],尽管提供了进行自动转换2to3
实用工具,仍有大量现存代码不能移植,故而Python 2.7的产品寿命结束延期至2020年元旦。Python 3.4介入了异步I/O模块[63]。Python 3.5介入了类型提示[64],和采用async/await语法的协程[65]。Python 3.8介入了赋值表达式[66][67]。
在2020年10月,Python 3.9介入了内建的针对容器类的泛化别名(types.GenericAlias
)类型[68],并在官方实现中介入了新的语法解析器[69]。Python 3.10介入了结构式模式匹配[70],和内建的联合类型(types.UnionType
)[71]。Python 3.11对官方实现进行了优化提速[72]。Python 3.12介入了类型参数语法和type
语句[73],并废弃或移除了一些过时的模块和功能。Python 3.13介入了新的交互式解释器,并实验性的支持了在自由线程模态下运行和即时编译器[74]。
每个版本首次发行后,享有2年的完全支持,随后是3年的安全支持。当前只有Python 3的稳定版本3.12与3.13正在被完全支持,但仍提供对3.9、3.10和3.11版本的安全性修正[75]。
在2023年12月,活跃的Python核心开发者,选举Pablo Galindo Salgado、Gregory P. Smith、Barry Warsaw、Emily Morehouse和Thomas Wouters,为2024年度“掌控委员会”的五位成员来领导这个项目[76]。
特徵與設計哲學
[编辑]Python是多范型编程语言。它完全支持结构化编程和面向对象编程,还有很多特征支持函数式编程和元编程比如元对象协议(元类和魔术方法[77])。通过扩展还可以支持很多范型,包括面向方面编程[78]、契约式设计[79]和逻辑编程[80]。
Python使用动态类型,在内存管理上采用的垃圾回收器基于了引用计数[81],并且结合了检测环引用的分代垃圾回收优化[82]。它的特征还有动态名字解析(后期绑定),即在程序执行期间绑定方法和变量的名字。
Python對遵循LISP傳統的函数式编程提供了有限的支持[83],它提供了 map
、filter
和reduce
函数[84];列表推导式、字典、集合和生成器表达式。標準庫中的模組functools
和itertools
,实现了从Haskell和Standard ML借鉴来的函數式工具[85]。
Python的設計理念是“優雅”、“明確”、“簡單”,它的一些重要準則被合稱為「Python之禅」。在Python解釋器内運行import this
可以獲得完整的列表,下面举出其中首要:
- 優美优于丑陋。明瞭优于隐晦。
- 简单优于复杂。复杂优于凌乱。
- 扁平优于嵌套。稀疏优于稠密。
- 可读性很重要。
Python開發者的方法论是“用一種方法,最好是只有一種方法來做一件事”,显著不同于以Perl语言为代表的“不止一种方法去做一件事”風格。Python開發者在設計語言時,如果面臨多種選擇,一般會選擇明確没有或者很少有歧義的語法。
范羅蘇姆认为ABC語言非常優美和强大,它没有取得成功的原因是不開放造成的[86],故而将Python本身設計為可擴充的[87]。Python並不把所有的特性和功能都集成到語言核心,而是提供了豐富的API和工具,以便程式設計師能够輕鬆地使用Python、C语言、Cython來編寫擴充模組。Python还可以通过外界函数接口如标准库中的ctypes等,来提供C语言兼容数据类型,并访问动态链接库或共享库中的函数[88],从而对用其他語言編寫的程式進行集成和封裝。
在Python的官方实现CPython中,一般避開不成熟的或者對非重要部位的加快運行速度的優化。在某些對運行速度要求很高的情況,可以使用具备JIT技术的Python实现或安装JIT扩展模块[89]。
語法和语义
[编辑]Python為了讓程式碼具備高度的可閱讀性,在設計時盡量使用了其它語言常用的符號和英文單字。
行结构
[编辑]Python支持使用反斜杠作为行接续符,将多个物理行合成为一个逻辑行[90]。在圆括号、方括号或花括号之中的表达式,可以分裂跨越多于一个物理行而不使用反斜杠,这被称为“隐式行接续”[90]。注释开始于并非字符串文字一部份的一个井号#
,并结束于物理行结尾;注释标示逻辑行的结束,除非已受制于隐式行接续规则;注释在语法上被忽略[91]。
简单语句包含在一个单一的逻辑行之内,Python支持使用分号作为分隔符,将多个简单语句合并入语法意义上的一行之中[92]。
縮排
[编辑]Python语法中的复合语句,包含(成组的)其他语句;它们以某种方式影响或控制这些其他语句的执行。Python的复合语句包含一个或多个子句(clause),子句构成自一个头部(header)和一个套件(suite)。特定复合语句的子句头部都在同样的缩排层级上,每个子句头部开始于一个唯一标识关键字,并结束于一个冒号。套件是这个子句所控制的一组语句,套件有两种形式,可以是与头部在同一行上的一个或多个由分号分隔的简单语句,它们跟随在这个头部的冒号之后;或者是在后续诸行上的一个或多个缩排的语句,只有这种套件形式可以包含嵌套的复合语句[93]。
Python語言遵循越位規則,利用縮排来形成语句套件,即语法意义上的块。连续诸行的缩排层级,被用来生成语法解析器才能见到的INDENT
和DEDENT
记号[94],二者的作用相当于C语言家族的花括号,或Pascal语言家族的关键字begin
和end
。增加縮排就生成INDENT
记号,減少縮排就生成DEDENT
记号。根據PEP 8的規定[95],使用4個空格來表示每級縮排。[a]
tab字符(从左至右)被替代为1至8个空格,使得直到tab之前的诸字符加上这些替代空格的字符总数,是8的倍数(这意图同于Unix所用规则)。前导于第一个非空白字符的空格的总数,确定了这一行的缩排层级。缩排所用诸字符,不能使用反斜杠来拆分成多个物理行;直到第一个反斜杠之前的空白确定缩排层级。如果源代码文件混合了tab和空格,并且在这种方式下缩排的意义依赖于一个tab相当于多少个空格,则这种缩排因不一致性而被报错并拒绝[96]。
关键字
[编辑]Python有如下35个关键字;它们不能用作标识符[97]:
|
|
|
|
|
|
|
内建常量True
、False
和None
于Python版本3.0中成为关键字,关键字nonlocal
介入于版本3.0[98],关键字async
和await
介入于版本3.5[99],并在版本3.7中成为正式关键字[100]。
在Python中,将只在特定上下文中保留的标识符,称为“软关键字”[101]:
match
、case
和通配符_
,介入于版本3.10,它们在与模式匹配语句有关的上下文中,可以在语法上充当关键字;但是这种区分只在语法解析器层次进行,并非在词法分析记号化层次。type
,介入于版本3.12,它用在type
语句之中。
标识符
[编辑]标识符就是名字,在ASCII范围内(U+0001..U+007F),可用于标识符的字符为:大写字母A
至Z
和小写字母a
至z
,下划线_
以及数字0
至9
,但首字不可以用数字。如下命名约定[102],是为“保留标识符类”[103]:
_spam
(单下划线开头):弱“内部使用”标识。对于from M import *
,将不导入所有以下划线开头的对象。spam_
(单下划线结尾):为了避免与python关键字的命名冲突。__spam
(双下划线开头):在命名一个类特性的时候,采用名字修饰,比如在类SpamEggs
内,__spam
将变成_SpamEggs__spam
[104]。__spam__
(双下划线开头双下划线结尾):指那些包含在用户控制的命名空间中的“魔术”方法或特性,比如__delattr__
、__dir__
、__doc__
、__getattribute__
、__init__
、__new__
、__repr__
、__setattr__
、__sizeof__
等。建议永远不要将这样的命名方式应用于自己的变量或函数。
在Python文献中经常使用的元语法变量是spam和eggs而非传统的foo和bar[104]。
語句
[编辑]Python的语句包括简单语句:
- 赋值语句,采用的中缀记号是等号
=
。赋值语句被用来将名字绑定(含重新绑定)到值,以及用来修改可变对象的特性或项目。 - 表达式语句,用来交互式的计算并写出一个值,或者用来调用一个过程(即返回无含义结果的函数),在Python中过程返回值
None
。 global
语句,是在整个当前代码块中成立的声明,它意味着随后列出的标识符被解释为全局变量。nonlocal
语句,导致随后列出的标识符,提及在除了全局作用域之外的最近包围作用域中的先前绑定变量。type
语句,介入于版本3.12,声明作为类型别名类型(typing.TypeAliasType
)的实例的一个类型别名。pass
語句,充当NOP,表示此行為空,不執行任何操作。assert
語句,用於程式調適階段時測試執行條件是否滿足。continue
语句,越过这次迭代并继续进行下个项目。break
语句,从循环中跳出。return
语句,用来从函数返回值。当函数执行到return
语句时,它会停止执行并将指定的值返回给调用者。raise
语句,抛出一个例外。yield
语句,使用它从一个生成器中返回一个值。在版本2.5之前,信息只能单向的从生成器传递出来。[c]import
语句,导入一个模块或包,它组合了两种操作,查找指名的模块,接着将找到的结果绑定到在局部作用域中的名字。导入语句有三种形式(下述语句样本中的方括号表示其中内容为可选的):del
语句,递归的进行删除。
复合语句:
if
語句,當條件成立時執行語句套件。它經常包含elif
、else
子句。while
語句,當條件為真時,重複執行語句套件。for
語句,遍历列表、字符串、字典、集合等迭代器,依次處理迭代器中的每個元素。match
语句,用于模式匹配。try
語句,它经常包含except
、else
、finally
子句,處理在程式執行中出现的異常情況。Python支持并广泛使用例外处理,作为检测错误状况和程序中其他“例外”事件的方式,并提倡在可能出现错误状况的任何时候都使用例外。习惯上访问一个文件或资源不在使用之前进行测试,而是先行尝试使用它,再捕获访问被拒绝引发的例外。[e]Python 3.11介入了except*
子句[116]。with
語句,把一块代码包裹在一个上下文管理器之内。它允许了资源获取即初始化(RAII)式行为,可替代常见的try
/finally
惯用法。Python使用with
语句处理资源[117],在进入一个作用域的时候调用一个函数,而在离开它的时候调用另一个函数,例如:在一块代码执行之前获取一个锁,并且在此后释放这个锁;或事先打开一个文件,并且事后关闭它。[f]class
語句,是定义类的可执行语句。类的继承列表给出基础类列表,没有继承列表的类,缺省继承基础类object
。类的套件接着在新的执行框架(frame)中执行,它使用新建的局部名字空间和原来的全局名字空间。当这个类套件完成执行之时,丢弃它的执行框架并保存它的局部名字空间。一个类对象接着被创建,其基础类采用继承列表,其特性字典采用保存的局部名字空间。类名字接着在原来的局部名字空间中,被绑定到这个类对象。def
語句,是定義函數和方法的可执行语句。它的执行在当前局部名字空间中,将函数名字绑定到一个函数对象(对函数的可执行代码的包装器)。这个函数对象包含到当前全局名字空间的引用,作为调用这个函数时使用的全局名字空间。async def
语句,用于协程函数定义。await
表达式、async for
语句和async with
语句,只能用在协程函数的主体中。[g]
块与模块
[编辑]Python程序构造自代码块。块是作为一个单元执行的Python程序文本,模块、函数主体和类定义都是块。交互式键入的每个命令、脚本文件和脚本命令都是代码块。传递给内建函数eval()
和exec()
执行的字符串是代码块。
代码块在执行框架(frame)中执行。框架包含一些用于调试的管理信息,并确定在这个代码块执行完成后,执行在何处以及如何继续。名字空间是存储变量的地方,它被实现为字典。有局部名字空间、全局空间即包含此代码块的那个模块的名字空间,和内建名字空间即模块builtins
的名字空间;对象的方法是定义在类主体内的函数,它有着嵌套的名字空间。名字空间通过防止命名冲突而支持了模块性,还通过明晰了哪个模块实现了哪个函数而增进可读性和可维护性。
模块是包含Python定义和语句的一个文件,这个文件名字是模块名字附加上后缀.py
;在一个模块中,模块的名字(作为字符串)可获得为全局变量__name__
的值[115]。包(package)是可以包含子模块或递归性的子包的模块。包在技术上是具有__path__
特性的Python模块。可以将包视为文件系统上的目录,而将模块视为这种目录中的文件,但是包和模块不必然源自文件系统[118]。
完整的Python程序,在一个极小初始化的环境中执行:所有内建和标准模块均可获得,但除了sys
(各种系统服务)、builtins
(内建函数、例外和None
)和__main__
之外都未被初始化。__main__
用来为完整程序的执行提供局部和全局名字。当解释器被调用在交互模态下的时候,它一次一个的读取并执行语句;初始环境同于完整程序,每个语句都在__main__
的名字空间中执行。
顶层代码是启动运行的首个用户指定Python模块。__main__
是顶层代码运行所在的环境。从命令行使用-m
参数,作为顶层脚本运行的模块(作为模块__main__
)是代码块。此时__name__
变量被设置为"__main__"
,籍此可在这个模块中增加直接运行时候执行的代码[115][119]。
名字是通用的引用持有者,它不关联于一个固定的数据类型,但是,一个名字在给定时间,总是被绑定到有一个类型的某个对象上,这就是动态类型的特征。名字的存储位置不“包含”所指示的值,一个共同的值可以赋值给多个名字,一个名字在任何时候,都可以重新绑定到各种不同类型的对象上,包括字符串、过程、具有数据和方法的复杂对象等。如果一个名字绑定在一个块中,它是这个块的局部变量,除非被声明为nonlocal
或global
。如果一个名字绑定在模块层次,它是全局变量。模块代码块的变量,既是局部的也是全局的。如果一个变量使用在一个代码块中,却不定义在这里,它是自由变量[120]。
内建vars()
函数,返回一个模块、类、实例或任何具有字典特性__dict__
的对象的字典特性。内建globals()
函数,返回实现当前模块的名字空间的一个字典。内建locals()
函数,更新并返回表示当前局部符号表的一个字典。在函数块中而非类块中调用locals()
之时,它返回自由变量。在模块层级上,locals()
和globals()
返回同一个字典。内建dir()
函数,在无参数时,返回在当前局部作用域内的名字列表;在有一个参数时,尝试返回这个对象的有效特性的列表。[121]
在Python中赋值所进行的操作,是将一个名字绑定为到一个分立的动态分配的对象的一个引用。除了在块中出现的每个赋值语句或导入语句之外,下列构造也绑定名字:给函数的形式参数、类定义、函数定义、赋值表达式、在for
语句头部中和各种as
关键字之后的标识符目标(target),as
关键字出现在import
语句、with
语句、except
子句、except*
子句和结构式模式匹配的as
模式之中。
作用域定义一个名字在一个块中的可见性。如果一个局部变量被定义在一个块中,它的作用域包括这个块。如果这个定义出现在一个函数块中,作用域扩展到在所界定作用域内包含的任何块,除非所包含的块为这个名字介入了不同的绑定。当一个名字在一个代码块之中使用,它采用最近包围作用域来解析。对一个代码块可见的所有这种作用域的集合,叫做这个这个块的“环境”[120]。
如果一个名字绑定在一个块中,并且在其中于绑定之前就被使用,会导致一个错误。[h] 如果global
语句出现在一个块之中,在这个语句中指定的所有名字,提及在顶层名字空间中这些名字的绑定。名字在顶层名字空间解析,首先查找全局名字空间,未果查找内建名字空间。global
语句与在同一个块中的名字绑定运算有同样的作用域。如果一个自由变量的最近包围作用域包含针对它的global
语句,这个自由变量被当作全局的[120]。[i] 当一个函数或类的定义被嵌套到其他函数的定义之内,它的非局部作用域就是这个包围函数的局部作用域。nonlocal
语句导致其列出的标识符,提及在非局部作用域内先前绑定的名字(即非局部变量)[120]。[j]
表达式
[编辑]Python中很多表达式与C语言和java类似,而另一些则与之不同。
- 在Python中,算术运算的加法
+
、减法-
、乘法*
和取模%
是与C语言和java相同的,但是除法的行为不同。在Python中有两种除法,它们是下取整除法(或整数除法)//
和浮点除法/
。Python增加了指数算符**
。自从Python 3.5,介入了矩阵乘法算符@
[122],它已经用于了NumPy库[123]。
- 在Python中,有如下必须用于整数的位运算:
&
与(AND),|
或(OR),~
非(NOT),^
异或(XOR),>>
右移,<<
左移。
- 在Python中,有如下比较运算:大于
>
,小于<
,等于==
,不等于!=
,小于等于<=
,大于等于>=
。==
按值比较。Python的is
、is not
算符可以用来比较对象的同一性(按引用比较),也就是比较两个变量是否引用了同一个对象。而in
、not in
用于判断一个对象是否属于另外一个对象。在Python中,比较是可以链接起来的[124],比如a < b < c
。
- 在Python中,由逗号
,
分隔的一组表达式,叫做表达式列表。Python为构造列表、字典或集合,提供了叫做“显示”的特殊语法,它们每个都有两种方式:包容内容要么显式列举出来;要么通过一组循环和过滤指令计算而来,这叫做“推导式”。列表显示是包围在方括号中的可以为空的一系列表达式,一个例子列表可写为[1,2,3]
。字典显示是包围在花括号中的可能为空的一系列的键/数据项对。集合显示用花括号来指示,与字典显示的区别是缺少分隔键与值的分号[125]。自从Python 3.5,增加了在表达式列表中的“可迭代解包”*
,和在字典显示中的“字典解包”**
[126]。[k]
- 在Python中,加圆括号形式(parenthesized form),是包围在圆括号中的一个可选表达式列表。加圆括号的表达式列表产生的东西,就是这个表达式列表所产生的:如果这个列表包含至少一个逗号,它产生一个元组;否则它产生构成这个表达式列表的那个单一表达式[128]。一个例子元组可写为
(1,2,3)
。元组不是圆括号形成的,而是使用逗号形成的,在没有歧义的情况下,元组的圆括号是可选的。空的圆括号对产生空元组对象。使用序列串接算符+
来串接二个元组,产生包含给定元组二者的元素的一个新元组。
- Python支持在序列对象(比如字符串、元组或列表)上的下标(subscription)表达式:
a[索引]
,和分片表达式:a[开始:停止]
或a[开始:停止:步长]
。下标索引是基于零的,负数是相对于结尾的。分片范围自从“开始”索引,直到但不包括“停止”索引。分片的第三个参数叫做“步长”(step)或“间隔”(stride),允许元素被跳过和用负数指示反向。分片索引可以省略,例如a[:]
,这返回整个列表的一个复本。[o]分片的每个元素都是浅层复制的。
- Python的条件表达式表示为
x if c else y
。意思是当c
为真时,表达式的值为x
,否则表达式的值为y
。 在运算元的次序上不同于很多其他语言中常见的c ? x : y
。
- 自从Python 3.8,介入了赋值表达式,其记号是
:=
[66]。它将一个表达式赋值给一个标识符,同时还返回这个表达式的值。赋值表达式在用作子表达式,即位于分片表达式、条件表达式、lambda
表达式、关键字参数中的表达式和推导式中的if
表达式之中,以及在assert
和with
语句之中的时候,必须围绕着圆括号。在它们可以使用的所有其他地方,包括在if
和while
语句之中,都不要求圆括号[129]。
Python中运算符具有优先级,下表中的运算符按照从最高到最低的次序列出。在相同单元格中运算符具有相同的优先级,它们从左至右结合,除了指数表达式和条件表达式从右至左结合之外[130]:
运算符 | 描述 |
---|---|
(表达式...) ,[表达式...] ,{键: 值...} ,{表达式...} | 加圆括号表达式,列表显示,字典显示,集合显示 |
x[索引] ,x[索引:索引] ,x(参数...) ,x.特性 | 下标,分片,调用,特性引用 |
await x | await 表达式 |
** | 指数 |
+x ,-x ,~x | 取原数,相反数,逐位NOT |
* ,@ ,/ ,// ,% | 乘法,矩阵乘法,除法,下取整除法,余数 |
+ ,- | 加法和减法 |
<< ,>> | 移位 |
& | 逐位AND |
^ | 逐位XOR |
| | 逐位OR |
in ,not in ,is ,is not ,< ,<= ,> ,>= ,!= ,== | 包含成员关系测试,同一测试,各种比较 |
not x | 布尔NOT |
and | 布尔AND |
or | 布尔OR |
if – else | 条件表达式 |
lambda | lambda表达式 |
:= | 赋值表达式 |
Python提供了序列串接算符+
和序列倍增算符*
[131]。自从Python 3.9,介入了字典归并算符|
和字典更新算符|=
[132]。
Python的文本序列类型,包括字符串str
和字节序列bytes
与bytearray
。字符串文字有多种写法,字符串对象有一个内建格式算符%
:
- 短字符串文字,由单引号
'
或双引号"
界定。不同于Unix shell、Perl和受Perl影响的语言,单引号和双引号功能相同。这二种字符串都使用反斜杠\
作为转义字符。
- 字符串文字或字节文字都可选的能前缀上一个
r
或R
,这叫做原始字符串。转义序列不被解释,因此在文字反斜杠常见的地方很有用,比如正则表达式和Windows风格的路径。[r]这种引述可比较于C#中的“@
引述”。
- Python中的“字符串格式”算符
%
,在功能上类同于C语言中的printf
格式化字符串[134],例如"spam=%s eggs=%04d" % ("blah", 2)
,求值为'spam=blah eggs=0002'
。自从Python 3.0,str
类提供了可供替代的format()
方法[135],例如"spam={0} eggs={1:04d}".format("blah", 2)
。在Python 3.6中,提供了“格式化字符串文字”或称为“f字符串”,它向字符串文字前缀上f
或F
[136],这是一种字符串插值[137],例如x="blah"; y=2; f'spam={x} eggs={y:04d}'
。[t]
在Python中,在表达式和语句之间的区别是严格强制性的,这对比于语言如Common Lisp、Scheme或Ruby。故而Python中个别构造存在功能重复,比如:列表推导式相当for
循环;条件表达式相当if
语句;内建函数eval()
相当exec()
,前者用于表达式,后者用于语句。
语句不能成为表达式的一部份,由于列表和其他推导式或lambda表达式,都是表达式,也就不能包含语句。这个限制的一个示例:赋值语句比如a = 1
,不能用作条件语句的条件判断表达式的一部份;这能够避免C语言编程中的一个常见错误,即在条件判断时把等于算符==
误写为赋值算符=
,这不是预期代码却在语法上有效而能通过编译器检查,在Python中这会导致一个语法错误。
函数
[编辑]Python的函数支持递归和闭包[u] ,及其他头等函数特征,但不支持函数重载。Python的函数作为头等对象,具有和普通对象平等的地位。Python官方实现不提供尾调用优化或头等续体,吉多·范罗苏姆曾声称永远都不会加以支持[138],但有第三方库支持弹跳床[139]。
Python可以在函数定义时,于形式参数序列中,指定形式参数缺省值,即以param=value
样式进行一次性初始化。形式参数在初始化之后,保持既有绑定;函数的后续调用,可继续对它进行访问或变更。[v]为有缺省值的形式参数提供实际参数,在函数调用时是可选的。
Python的函数实际参数与形式参数之间的结合,是传递“对象引用”,函数在被调用的时候,给函数调用的实际参数,被介入到一个局部符号表中,实际参数使用传值调用来传递,而这个值总是对象引用,而非这个对象的值[140]。如果形式参数绑定到一个可变的对象,则通过形式参数对此对象内容的修改,在函数外也是可见的。如果形式参数绑定到一个不可变的对象,则通过形式参数是不能修改此对象内容,但可以把形式参数重新绑定到其它对象上,这并不影响函数外的对象的值。[w]
Python支持位置实际参数和关键字实际参数。函数调用时,实际参数可以如同C语言那样,按照位置与形式参数匹配;也可以采用命名参数或称为关键字实际参数,即kwarg=value
样式的实际参数。使用不对应实际参数的特殊形式参数/
和*
,可以将参数序列分为三部份:唯位置参数[141]、可位置可关键字参数和唯关键字参数。有缺省值的形式参数之后,不能跟随无缺省值的可位置形式参数。[x]在一个函数调用的实际参数序列中,关键字实际参数必须出现在位置实际参数之后。
在位置和关键字形式参数序列末尾,可以分别有*args
或**kwargs
这样的形式参数,它们对应于在函数调用时提供的,超出形式参数序列规定而无所对应的多个实际参数;在形式参数名字前加一个*
号,该形式参数args
是tuple
类型,对应可变数目的位置实际参数;在形式参数名字前加**
号,该形式参数kwargs
是dict
类型,对应可变数目的关键字实际参数。[y]如果位置实际参数已经在一个序列类型如列表或元组的对象中,在引用它的变量前加一个*
号传递给函数,则其中所有元素解包为多个位置实际参数;如果关键字实际参数在字典中,则加**
号来传递给函数。
修饰器(decorator)可用来修改一个函数、方法或类定义的任何可调用Python对象。将已定义的原来对象传递给修饰器,它返回一个修改后的对象,接着把它绑定到在定义中那个名字。Python修饰器部份受到Java注解的影响,而有类似的语法;修饰器语法是纯粹的语法糖,使用@
作为关键字形成修饰符。修饰器是一种形式的元编程,它们增强它们所修饰的函数或方法的行动。[z] 多个修饰器可以链接起来,通过在毗连的行上放置多个修饰符,或者使用中间变量。[aa] 函数修饰器的正规用法包括:用来建立类方法或静态方法[59]、设置先决条件和后置条件、实现多方法、增加函数特性、跟踪、同步[142];此外更远大的用法包括:尾调用消除、记忆化[143]。
为了增强代码的可读性,可以在函数后书写“文档字符串”(简称docstrings),用于解释函数的作用、参数的类型与意义、返回值类型与取值范围等。可以使用内置函数help()
,打印出函数的使用帮助。[ab]自从Python 3.0,函数可以对参数与返回值增加类型标注[144]。此特性可方便对源代码进行更深入的分析。[ac]自从Python 3.5,开始支持类型提示[145]。
对象及其方法
[编辑]Python支持大多数面向对象编程技术。在Python中所有东西都是对象,包括类、函数、数和模块。它允许多态性,不只是在类层级之内,而且通过采用鸭子类型的方式[7]。任何对象可以用于任何类型,只要它有适当的方法和特性(attribute)就能工作。Python天然支持类的继承包括多重继承,为此采用C3线性化或方法决定次序(MRO)算法,还支持混入。Python支持元类[146],自从Python 3.6,提供了定制类创建的简单机制[147]。
Python使用名字修饰,有限的支持私有变量。对象的(可写)特性可以被提取为一个字典[148]。在Python中,不强制使用访问子与变异子方法,来访问数据成员的面向对象编程信条。就像Python提供函数式编程构造,但不尝试要求参照透明性一样,它提供对象系统,但不要求面向对象编程行为。
对象的方法,是附属于这个对象的类的函数。对于正常的方法和函数,语法instance.method(arguments)
,是Class.method(instance, arguments)
的语法糖。Python的方法有显式的self
形式参数,用来访问实例数据;这借鉴自Modula-3,对立于隐式的self
或this
关键字,它们用在其他一些面向对象编程语言,比如C++、Java、Objective-C或Ruby之中[149]。在Python中,self
可以被看作是一个习惯用法,它可以被换为任何其它合法的参数名。[ad]
Python提供了super()
内建函数,在一个类的方法中调用此函数返回一个代理(proxy)对象,它将其方法调用委托给这个类的父类或兄弟类[150],当一个子类的方法覆盖了超类方法的时候,可通过调用super().method
,来调用与子类的self.method
方法同名超类方法。[ae] Python支持一些以__
开始和结束的特殊方法名,它们用于实现运算符重载,以及实现多种特殊功能[77]。在Python中,可以通过定义特殊方法来重载运算符,比如在一个类上定义__add__()
,将允许在这个类的实例上使用+
算符。
在Python中,定义了一个或多个特殊方法__get__()
、__set__()
、__delete__()
的类,可以用作描述器(descriptor)[151]。建立一个描述器的实例,作为另一个类的一个类成员,使得这个实例成为此另一个类的属性(property)。使用与特性(attribute)访问相同的语法,访问一个实例对象中的这个成员属性。[af]
Python允许通过使用@classmethod
和@staticmethod
修饰符,来分别建立类方法和静态方法[59]。给类方法的第一个实际参数,是对类对象的引用,而非对实例的self
引用。静态方法没有特定的第一个实际参数,实例或类对象,都不固定的传递给静态方法。[ag] Python的property
内建函数,将一个类中特殊定义的访问一个特性的那些方法,包装成的这个类的一个属性[152]。[ah]
类型
[编辑]Python使用鸭子类型,并拥有有类型的对象,和无类型的变量名字。在编译期不检查类型约束,而宁愿在一个对象上的操作出现可能的失败,表现出这个给定对象不具有适合的类型。尽管是动态类型系统,Python却是强类型的,禁止没有明确定义的操作(比如加一个数到一个字符串),而不是默默的去尝试转换使其有意义。Python支持广泛的类型和类的内省。类型是type
的实例,可以被读取和比较。
Python有着范围广泛的基本数据类型。同时具备常规的整数和浮点算术,它透明的支持任意精度算术、复数和十进制浮点数。Python支持种类繁多的字符串操作。在Python中,字符串是不可变的,所以在其他编程语言中可能就地改变字符串的字符串操作,比如字符替换,在Python中返回新的字符串。
Python有一个非常有用特征,就是搜集(或称容器)类型的概念。一般的说,搜集是以一种易于引用或索引的方式,包含其他对象的对象。搜集有二种基本形式:序列和映射。Python对建立容器类型的对象有着语法上的支持。[ai]Python还提供了广泛的搜集操纵能力,比如内建的包含元素检查和通用迭代协议。
有次序的序列类型是列表(动态数组)、元组和字符串。所有序列类型都是位置索引的(从0
到长度−1
),并且除了字符串,都可以包含任意类型的对象,在同一个序列中包括多种类型的对象。字符串和元组是不可变的,使得它们成为字典的键的完美候选者。在另一方面,列表是可变的,元素可以被插入、删除、修改、添加或就地排序。
在另一方面,映射是以“字典”形式实现的无次序的类型,它将一组不可变的键,映射到相应的元素上(非常像数学函数)。在字典中的键,必须是不可变的Python类型,比如整数或字符串,因为在底层它们是通过散列函数实现的。字典还是语言内部的中心,因为它们居于所有Python对象和类的核心:在变量名字(字符串)和这个名字所引用的值之间的映射,就存储为字典,而这些字典可以通过对象的__dict__
特性直接访问。
集合搜集类型,在版本2.4中被增加入语言核心。集合是无索引、无次序的搜集,它包含唯一性的不可变对象作为元素,并且实现了集合论运算,比如并集|
、交集&
、相对补集-
、对称差^
,和子集测试<=
、真子集测试<
、超集测试>=
、真超集测试>
。有二种类型的集合:可变的set
和不可变的frozenset
。
Python允许编程者使用类,定义自己的类型[55],类是在面向对象编程中最经常使用的。类的新实例,是通过调用这个类的构造器而创建的,而类都是元类type
的实例,type
是type
元类自身的实例,这允许了元编程和反射。[aj]
在版本3.0之前,Python有两种类:旧式的和新式的[154]。二种样式的语法是一样的,不同在于是否直接或间接的继承自类object
,所有新式类都从object
继承,并且是type
的实例。在Python 2系列2.2以上,二种类都可以使用[55]。在Python 3.0中淘汰了旧式类。
长期规划是支持渐进类型[9],并且自从Python 3.5,语言的语法允许指定静态类型,但在缺省实现CPython中不检查它们[145]。有叫做“mypy”的可选的静态类型检查器,支持编译期类型检查[155]。
类型 | 可变性 | 描述 | 语法例子 |
---|---|---|---|
bool | 不可变 | 布尔值,有表示值False 和True 的两个对象。作为整数类型numbers.Integral 的子类型,它们在几乎所有上下文中,表现得如同0 和1 ,除了在转换成字符串时转换为"False" 和"True" 之外。 | True False |
int | 不可变 | 整数,其大小在理论上无限制,实际上受限于内存[156]。 | 42 |
float | 不可变 | 双精度浮点数,确切精度依赖于机器。一般实现为IEEE 754标准binary64浮点数,它有53个二进制有效数位精度[157]。 | 1.414 |
complex | 不可变 | 複數,即分别表示实部与虚部的两个双精度浮点数的有序对。 | 3+2.7j |
range | 不可变 | 数的序列,通常用在for 循环中指定循环次数[158]。 | range(1, 10) range(10, -5, -2) |
str | 不可变 | 字符串,即Unicode代码点序列。字符串中的代码点都在范围U+0000..U+10FFFF 之内。Python没有char 类型,这些代码点都表示为长度为1 的字符串对象。 | 'Wikipedia' "Wikipedia" """Spanning multiple lines""" |
bytes | 不可变 | 字节序列,其项目是8位字节,用范围0 <= x < 256 的整数表示。 | b'Some ASCII' b"Some ASCII" bytes([0x53, 0x74, 0x72]) |
bytearray | 可变 | bytearray(b'Some ASCII') bytearray(b"Some ASCII") bytearray([0x53, 0x74, 0x72]) | |
list | 可变 | 列表,可以包含任意的Python对象。 | [4.0, 'string', True] [] |
tuple | 不可变 | 元组,可以包含任意的Python对象。只有一个项目的元组,可以通过向表达式后缀一个逗号来形成。 | (4.0, 'string', True) ('single element',) () |
dict | 可变 | 键-值对的关联数组(常称为字典),即由任意索引集合来索引的对象的有限集合。不可接受为键的值,是列表或字典,或按值而非对象同一性比较的其他可变类型的值,其散列值不能保持恒定。 | {'key1': 1.0, 3: False} {} |
set | 可变 | 无序有限集合,包含唯一性的不可变的对象,它们不能用任何下标来索引。 | {4.0, 'string', True} set() |
frozenset | 不可变 | frozenset([4.0, 'string', True]) | |
types.EllipsisType | 不可变 | 这个类型有一个单一对象作为值,它通过文字... 或内建名字Ellipsis 来访问,它的真值为真。它用于NumPy多维阵列索引[159]。 | ... Ellipsis |
types.NoneType | 不可变 | 这个类型有叫做None 的一个单一对象Null 作为值[160],它被用来指示值的缺席,比如不返回任何东西的函数返回它,它的真值为假。 | None |
types.NotImplementedType | 不可变 | 这个类型有一个单一对象NotImplemented 作为值。数值方法和细化比较方法,在它们仍未对提供的运算元实现这个运算之时,返回这个值。它不应该在布尔值上下文中求值。 | NotImplemented |
除了各种数据类型,Python解释器还内建了很多其他类型,包括可调用类型:用户定义函数、实例方法、生成器函数、协程函数、异步生成器函数、内建函数、内建方法、类、类方法;模块,定制类,类实例,I/O对象(也叫做文件对象),和暴露给用户的一些内部类型:代码对象、框架对象、溯回对象、切片对象、静态方法对象、类方法对象。
算术运算
[编辑]Python的算术运算,使用平常的符号+
、-
、*
、/
和模除%
。它还有下取整除法算符//
、指数算符**
和矩阵乘法算符@
[122]。二元运算先将两运算元转为共同类型,加法、减法、乘法、下取整除法和指数运算的结果也采用此类型,比如5**3 == 125
而9**0.5 == 3.0
。这些算符就像在传统数学中一样运算,具有同样的优先级规则,中缀算符+
、-
,还可以分别表示取原数和取相反数的一元算符。
被称为“真除法”的/
的表现,随着版本不同而有着显著变化[161]。自Python 3.0以来,/
总是产生浮点数结果,包括两个整数相除,比如5/2 == 2.5
;而在下取整除法//
中,两个整数相除产生整数,比如7//3 == 2
而7.5//3 == 2.0
。
下取整除法//
的修约是朝向负无穷的。向下取整能增加一致性[162],例如这意味着等式(a + n)//n == a//n + 1
总是为真。模除%
所得出的余数的符号同于除数,比如-4%3 == 2
而4%-3 == -2
。其它多数编程语言比如C99采用截尾取整规则,余数的符号同于被除数。模除运算结果余数的定义,确使等式a == (a//n)*n + a%n
对于a
和n
分别为正数或负数的情况都是有效的[163]。余数可以为负数,显著不同于在数学中的欧几里得除法规则下,余数总是非负数的情况。
Python提供了round()
内建函数,用于把一个浮点数修约成最近的整数[164],自Python 3.0以来,为了打破平局它采用了IEEE 754的约半成偶规则:round(1.5)
和round(2.5)
都产生2
。
Python允许由比较运算链接起来的布尔表达式,表现得如在数学中常用的一样。比如表达式a < b < c
,测试a < b and b < c
[124]。C语言将它解析为(a < b) < c
:即首先求值a < b
,其结果为0
或1
,接着把这个结果比较于c
[165]。
Python对所有整数运算,使用任意精度算术。在decimal
模块中的Decimal
类[166],提供十进制浮点数,具有用户可按需要而更改的缺省28个十进制有效数位精度,并有多种修约方式[167]。在fractions
模块中的Fraction
类,提供任意精度的有理数[168]。第三方库gmpy2[169],提供了到任意精度计算库GMP/MPIR、MPFR和MPC的接口。
除了求绝对值函数abs()
列入内建函数之外,大多数数学函数,处于math
和cmath
模块内。前者用于实数运算,而后者用于复数运算。[ak]由于Python有着广泛的数学库,特别是第三方库NumPy进一步扩展了固有能力,Python经常被用作科学脚本语言,来处理如数值数据处理和操纵等问题[170][171]。
标准库
[编辑]Python拥有一个强大的标准库[172]。Python标准库包括了如下功能:
程序代码实例
[编辑]一個在標準輸出設備上輸出Hello World的簡單程式,這種程式通常作為開始學習程式語言時的第一個程式,可将如下代码录入纯文本文件并随意命名比如program01.py
,然后执行这个程序python3 program01.py
:
print("Hello, world!")
Python也可以單步直譯執行。執行Python直譯器進入互動式命令列的環境,你可以在提示符號>>>
旁輸入print("Hello, world!")
,按Enter鍵輸出結果:
>>> print('Hello, world!') Hello, world!
计算正数的阶乘的程序代码:
n = int(input('輸入一個數,就會印出其階乘: ')) if n < 0: raise ValueError('錯誤,請輸入一個非負整數') fact = 1 for i in range(2, n + 1): fact *= i print(fact)
注意,在Python 3.0及以上版本中,print
是个函数,需要在要打印的字符串前后加上圆括号;在Python 2.6以下版本中,print
是一个关键字和命令而不加圆括号。
实现
[编辑]Python是一门跨平台的脚本语言,Python规定了一个Python语法规则,根据该规则可编写Python直譯器[173]。Python属于动态语言,其官方实现将Python程序编译成中间形式的字节码[174],并接着在它的虚拟机上执行[175],相较于C/C++和java的等编译语言而言运行速度较慢[176]。
- 活跃开发的实现
- CPython:官方的直譯器,需要区别于其他直譯器的时候才以CPython称呼。CPython默认采用全局解释器锁(GIL),以确保在任何时刻只有一个线程执行Python字节码;一些扩展模块被设计为在进行计算密集任务时释放GIL,还有在进行I/O时总是释放GIL[177]。
- PyPy:用RPython编写的Python实现,兼容至CPython版本3.10和2.7,它采用了跟踪JIT,缺省支持stackless模态。
- MicroPython:为微控制器而优化的Python 3变体,它实现了完整的Python 3.4语法,和补充自版本3.5的
async/await
关键字,和后来版本的一些选定特征;它提供了实现Python标准库模块功能子集的内建模块,和特定于微控制器的一些模块。CircuitPython是Adafruit开发的MicroPython分叉。 - Codon:使用了LLVM的高性能Python编译器[178],它将Python代码编译成本机机器代码,不带有任何运行时开销并且支持本机多线程,它的语义在数据类型等方面上与CPython有所不同[179],它由MIT CSAIL的研究人员开发[180]。
- Pyodide:基于WebAssembly/Emscripten的用于浏览器和Node.js的Python发布[181],支持任何在PyPI上
wheel
形式的纯Python包,并且已经移植了很多具有C语言扩展的包。 - RustPython:用Rust编写的Python解释器[182],它可以嵌入到Rust应用程序中从而将Python用作脚本语言,还可以被编译成WebAssembly从而在浏览器中运行Python代码。
- Brython:用JavaScript编写的在浏览器中运行的Python实现[183],具有到DOM元素和事件的接口。
- 到其他语言的交叉编译器
- Cython:优化静态编译器,将Python超集编译成C语言或C++。Cython补充支持调用C语言函数并且在变量和类特性上声明C语言类型,还支持以OpenMP为后端的本机多线程并行[184]。
- Numba:使用LLVM的JIT编译器,将包括很多NumPy函数的聚焦数值计算的Python子集,翻译成快速的机器码,它为在CPU和GPU上并行化Python代码提供了大量选项。
- mypyc:将Python模块编译成C扩展的编译器[185],它使用标准的Python类型提示生成快速代码。mypyc是mypy发行的可选依赖,它使用mypy进行类型检查和类型推论[155]。
- Pythran:将聚焦于科学计算的Python子集编译成C++11的提前编译器[186],它依赖于Boost和xsimd库,将标注了接口描述的Python模块编译为本机共享库模块,能利于上多核和SIMD指令单元。
- Nuitka:用Python编写的到C11(或替补为C++03)的优化编译器[187],它依赖于CPython的
libpython
库,能完成嵌入所有模块的程序编译、扩展模块及包编译和独立模态程序发布。 - Transcrypt:用Python编写的Python 3.9到JavaScript编译器[188],用于在浏览器中运行Python代码,它被预先编译为高可读性且高效的JavaScript代码。
- MyHDL:将Python编译成Verilog或VHDL[189]。
其他实现举例:Jython,它是用Java实现的Python 2.7。IronPython,它是建造在DLR之上的Python 2.7和Python 3.4实现。Stackless Python,它是实现微线程的CPython 3.8分叉。Pyston,它是具有JIT等性能优化的CPython 3.8.12的分叉[190]。Pyjion,将Python代码编译成本机CIL的CPython 3.10的JIT扩展[191]。Cinder,它是Meta孵化器发布的具有包括JIT等很多优化的CPython 3.10分叉[192]。
开发环境
[编辑]通用文本编辑器
[编辑]很多并非集成开发环境软件的文本编辑器,也对Python有不同程度的支持,并且加上专门为Python设计的编辑器插件也会有很高的可用性。
专用开发环境
[编辑]适用于Python的集成开发环境(IDE)软件,除了标准二进制发布包所附的IDLE之外,还有许多其他选择。其中有些软件设计有语法着色、语法检查、运行调试、自动补全、智能感知等便利功能。由于Python的跨平台出身,这些软件往往也具备各种操作系统的版本或一定的移植性。
- IDLE:Python“标准”IDE,一般随Python而安装,支持较少的编辑功能,调试功能也比较弱。
- Eric:基于PyQt的自由的IDE,支持自动补全、智能感知、自动语法检查、工程管理、svn/mercurial集成、自动单元测试等功能,具有可扩展的插件系统,通过可选插件支持Git集成。调试功能与Visual Studio和Eclipse类似。
- Spyder:开源的跨平台科学计算IDE。
- PyScripter:功能较全的开源IDE,使用Delphi开发。
- PyCharm:由JetBrains公司出品,具备一般IDE的功能,比如调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制等等,另外,它还提供了一些功能用于Django开发,同时支持Google App Engine,还支持IronPython。它是商业软件,但也具有社区版和教育版。
- Thonny:适用于编程初学者的IDE。
- Wing IDE:商业软件,有免費的功能有限的Wing 101。
第三方扩展包
[编辑]Python社群提供了大量的功能覆盖众多领域的第三方模組,其使用方式与标准库类似。第三方模块可以使用Python/Cython或者C语言编写。软件工具SWIG和SIP,通过定义接口文件或规定文件的方式,可以将C/C++编写的程序库包装为Python模块。Python解释器本身也可以被集成到其它需要腳本語言的程式内。
Python包索引是公开的软件包在线仓库。pip是官网推荐的以安全方式安装Python应用及其依赖软件包的最流行工具[193]。要安装在整个操作系统范围内共享的Python包,现在需要通过操作系统的软件包管理系统。要将特定于应用的依赖包隔离于共享的Python安装,可以使用标准库的venv[194]或第三方工具virtualenv[195]创建虚拟环境;第三方工具pipenv,能自动为用户项目建立和管理虚拟环境,并在安装/卸装软件包的时候,向此项目的Pipfile文件增加/移除这个软件包[196]。
網絡服务
[编辑]Python定義了WSGI標準應用接口,来協調HTTP伺服器與基於Python的Web程式之間的溝通。比如,通過mod_wsgi模組,Apache可以運行用Python編寫的Web程式。Zope是著名的用Python编写的开源的Web应用服务器。Tornado是用Python语言写成的非阻塞式web服务器,也是轻量级的Web框架。
Python對於各种網路協定的支援很完善,因此適用於編寫伺服器軟體、網路爬蟲等Web開發。用Python编写的一些Web框架,有助於輕鬆地開發和管理複雜的Web程式。著名的第三方Web框架和函数库:
- Django:MTV架构[197]的Web开发框架,注重组件的重用性和“可插拔性”、快速开发和DRY法则。
- Pyramid:极简主义的Web框架,不预定持久化方式。
- Flask:微Web框架,不要求特定的工具或库。
- PyScript:创建在浏览器内的Python应用的框架[198],这些应用能使用HTML界面和已编译成WebAssembly的Pyodide或MicroPython,以及当代Web技术。
- Twisted:事件驱动的网络编程框架。它支援多數標準的網路協定(包含客户端和伺服器),並且提供了多種工具,適用於編寫高性能的伺服器軟體。
- Requests:适合于常人使用的HTTP库,封装了许多繁琐的HTTP功能,极大地简化了HTTP请求所需要的代码量。
- Beautiful Soup:用来解析HTML/XML的一个简单易用Python包。
- uvloop:是对内建
asyncio
事件循环的快速的、直截了当的替代者[199],它用Cython实现并在底层使用了libuv。 - aiohttp:基于
asyncio
的HTTP客户端和服务器二者[200]。
图形用户界面
[编辑]Python本身包含了Tkinter库,它是Python的业界标准GUI并被集成进入了IDLE。Tkinter基于了Tcl命令工具,能够支持简单的GUI开发。但是为了让所开发的软件运行速度更快,并与用户的桌面环境更契合,人们一般会选择采用第三方GUI库或框架。著名的第三方GUI库:
- PyQt:Qt的Python绑定库,由Riverbank Computing公司自从1998年发行,采用GPL许可证或商业许可证。
- PySide:Qt的Python绑定库,由Qt公司自从2009年发行,采用LGPL许可证。
- PyGObject:替代了PyGTK,它是为Python程序访问基于GObject的库而提供的包装库[201],GObject是GTK、GIO和GStreamer等库使用的对象系统。
- Kivy:用于开发多点触控应用软件的开源Python库,采用了自然用户界面(NUI)。
- WxPython:GUI编程框架wxWidgets的Python包装库,它与MFC的架构相似。
- PySimpleGUI:将Tkinter、Qt、WxPython和Remi[202]的GUI框架变换成简单的接口[203]。
- Gooey:将几乎所有Python 3控制台程序用一行代码转变成GUI应用[204]。
- Dear PyGui:快速而强力的具有极小依赖性的GUI工具箱[205]。
- pywebview:轻量级跨平台的对WebView构件的包装器,允许在其本地GUI窗口中显示HTML内容[206]。
数据科学
[编辑]重要的数据科学用第三方软件库有:
- NumPy:Python的基础性的科学计算软件库,它提供了强力的多维阵列对象,广播式阵列运算[207],集成C/C++和Fortran代码的工具,较为有用的线性代数、傅里叶变换和随机数功能。
- SciPy:用于数学、科学和工程的Python软件库,它以NumPy的多维阵列作为基本数据结构,所包含的模块针对了:统计、最优化、数值积分、常微分方程求解、插值、线性代数、傅里叶变换、信号处理、图像处理等。
- CuPy:NumPy/SciPy兼容的GPU加速的阵列库[208],它可在NVIDIA CUDA或AMD ROCm平台上充当其直截了当的替代者,来运行现存的NumPy/SciPy代码。
- matplotlib:基于NumPy的综合性绘图库,用于创建静态的、动画的和交互式的数据可视化。
- pandas:用于数据分析和数据操纵的软件库,它建造在NumPy基础上,提供了加标签数据结构“数据帧”[209],和统计函数等。它的缺省绘图后端是matplotlib,还可以扩展上第三方绘图后端[210]。
- Dask:伸缩范围从笔记本电脑至计算机集群的并行计算库[211],它提供的用户接口镜像了PyData生态系统中pandas、scikit-learn和NumPy的API。
数据可视化
[编辑]- VisPy:高性能交互式2D/3D数据可视化库[213],它通过多种后端OpenGL库之一来显示非常大的数据集,并提供叫做gloo的受用NumPy的Python风格OpenGL ES 2.0接口。
- glumpy:用于科学数据可视化的快速、可伸缩的Python库[214],它基于了NumPy和OpenGL绑定库PyOpenGL。
- seaborn:基于matplotlib的数据可视化库[215],它提供了绘制统计图形的高层接口。
- Vega-Altair:建造在Vega-Lite JSON规定之上的声明式统计可视化库[216]。
- Bokeh:针对现代Web浏览器的交互式数据可视化库[217],它在大型或流式的数据集上提供高效的交互性。
- plotly:交互式开源的基于浏览器的图形绘制库[218],它是建造在plotly.js之上的声明式图表库。
- Dash:数据应用和仪表板框架,它可将现代用户界面元素如下拉选单、滑动条和图形,直接连结至分析型Python代码[219],它由Plotly公司出品,基于了React、Flask和plotly.js[220]。
- Panel:数据探索和Web应用框架,它能无缝的集成于PyData生态系统,提供交互式数据表格和可视化等功能[221],它是HoloViz生态系统的成员[222],这个工具组还包括了:hvPlot、HoloViews、GeoViews、Datashader、Lumen、Param和Colorcet。
- Streamlit:迅速将Python脚本转变为可共享Web应用的框架[223]。
- Voilà:将Jupyter Notebook转变为独立的Web应用的框架[224]。
机器学习
[编辑]基础性的机器学习软件库及框架有:
- scikit-learn:机器学习软件库,它提供的功能包括:监督学习中的分类和回归,无监督学习中的聚类和降维,还有模型选择和数据预处理。它基于了NumPy、SciPy、轻量级管道库Joblib[225]和线程池控制库threadpoolctl[226],其绘图功能依赖于matplotlib,还用到了scikit-image、seaborn和plotly。
- PyMC:基于从Theano分叉出的PyTensor的概率编程库,它用于建立贝叶斯统计模型,并使用马尔可夫链蒙特卡洛(MCMC)方法进行模型拟合。
- TensorFlow:Google开发的“端到端”开源机器学习平台,它提供了Python API[227],其中实现了Keras API[228]。Keras现在是在TensorFlow 2上建立的深度学习高层API。
- PyTorch:Meta在Torch基础上开发的开源的Python软件包,提供了具有强大的GPU加速的张量计算,和建立在基于tape的自动微分系统上的深度神经网络。
- JAX:Google开发的开源机器学习框架,其核心是可任意组合的对数值纯函数的变换[229],它结合了修改版本的针对NumPy的自动微分库Autograd[230],和TensorFlow中的加速线性代数库XLA[231],它使用XLA来在GPU和TPU上编译和运行NumPy程序。
其它种类
[编辑]- pegen:Python的PEG解析器生成器[232]。
- PeachPy:采用高层Python的可移植高效x86-64汇编代码生成器[233]。
- llvmlite:轻量级的LLVM的Python绑定,用于编写即时编译器[234]。
- SymPy:支持数学符号运算的软件库,用于提供计算机代数系统。
- SimPy:基于由Python生成器函数定义的进程的离散事件模拟框架[235]。
- ModernGL:不同于PyOpenGL[236],ModernGL是在OpenGL 3.3+核心上的Python包装器[237],它简化了简单图形应用如科学模拟、游戏和用户界面的创建。
- PyCUDA:不同于Nvidia的cuda-python[238],PyCUDA提供对CUDA API的Python风格访问[239]。
- PyOpenCL:PyOpenCL提供对OpenCL API的Python风格访问[240],例如光滑粒子流体动力学框架PySPH的性能关键部份用Cython和PyOpenCL实现[241]。
- Kompute:通用Vulkan计算框架,针对C++和Python[242]。
- Taichi:采用同Python几乎一样语法的指令式并行编程语言[243],它嵌入在Python之中并使用即时编译器框架如LLVM,将计算密集的Python代码转变成本机GPU或CPU指令。
- SQLAlchemy:Python的SQL工具包和采用数据映射器模式的对象关系映射器(ORM)。
- Graphene:GraphQL框架[244],支持各种数据源如SQLAlchemy、Mongo、Django和定制Python对象等。GQL是常用来与之配合的GraphQL客户端Python库[245]。
- Pillow:是基于Python的图像处理软件库[246],它支持广泛的图形文件格式,分叉于已终止的PIL。
- pypdf:能够分割、合并、修剪和转变PDF文件的Python软件库[247]。
- PyFilesystem2:Python的文件系统抽象层[248],将在归档、内存和云端存储等之中的文件和目录,像在本地驱动器中一样容易的处置。
- Fabric:经由SSH远程执行shell命令的高层库[249],它产生有用的Python对象作为回馈。
- Prefect:现代工作流程编排框架[250],它易于建造、调度和监控健壮的数据流水线。
- pygame:开发视频游戏的Python软件库,基于了SDL软件库[251]。视觉小说引擎Ren'Py建造在pygame之上。
- pyglet:Python编写的面向对象的游戏和多媒体库,利用了FFmpeg软件库并需要OpenGL 3.3+。2D街机游戏开发库Arcade基于了pyglet[252],它还利用了建造在2D物理引擎Chipmunk之上的Pymunk[253]。
- Panda3D:开源游戏引擎,包括了图形、音频、I/O、碰撞侦测和其他与3D游戏有关的功能,使用Python作为游戏开发语言[254]。
- pythonnet:可以近乎无缝的集成.NET通用语言运行库(CLR)的程序包[255]。
- PyInstaller:将Python应用和它的依赖项捆绑成一个单一的包[256],从而不需要安装Python解释器或任何模块就可以运行应用。
应用
[编辑]在很多作業系統裡,Python是標準的系统元件,它被列入Linux标准规范之中[257]。大多數Linux發行版和macOS都集成了Python,可以在终端模拟器或虚拟控制台下直接執行Python。第三方工具pipx,可以将Python应用安装于隔离的环境中并在其中运行它[258]。
雖然Python可被粗略地分類為腳本語言,Python的支持者較喜歡稱它為一種高階動態語言,常像“胶水”一样被用来连接软件组件,已经显著的区别于Unix shell、Windows PowerShell这样的语言。基于Python的xonsh,是跨平台的、青睐Unix的shell语言和命令行界面[259]。
应用程序
[编辑]一些Linux發行版,使用Python語言編寫安裝器,比如Ubuntu的Ubiquity和Fedora的Anaconda;或使用它編寫軟件包管理系统,比如Gentoo的Portage。如下著名应用使用Python编写或将它作为嵌入式脚本:
- IPython:以多种编程语言进行交互式计算的命令shell和Jupyter的内核,最初为Python开发,它提供了内省、富媒体、shell语法、tab补全和历史。
- Conda:跨平台的、语言无关的二进制包管理器,它被Anaconda发行采用。
- SCons:软件建造工具,它可代替make构建编译程序。
- Gunicorn:使用Python语言编写的WSGI Web服务器。
- Plone:基于Zope的内容管理系统。
- Mezzanine:基于Django框架的内容管理系统。
- Orange:基于scikit-learn和pandas的开源机器学习和数据可视化软件,由卢布尔雅那大学开发,利用了PyQt5和基于Blink的PyQtWebEngine,通过广大多样的工具箱来建造数据分析工作流程[260]。
- SageMath:涵盖许多数学功能的应用软件,它建造在NumPy、SciPy、matplotlib、SymPy、Maxima、GAP、FLINT、R等开源软件包之上。
- Veusz:用Python、PyQt和NumPy写成的科学绘图软件,可生成出版水准的PDF或SVG输出。
- MayaVi:基于VTK的应用程序和库,用于交互式科学数据可视化和采用Python的3D绘图[261]。
- Blender:開源3D繪圖軟體,使用Python作為建模工具與GUI語言。
- Inkscape:开源的SVG矢量图形编辑器,使用Python用于插件。
- Pitivi:用Python开发的基于GStreamer的视频编辑软件。
人工智能
[编辑]经由Python开发了众多的人工智能模型和作为其支撑的软件库:
- Ray:对人工智能及Python应用的运行规模进行伸缩的统一框架[262],由Anyscale公司开发。它构成自一个核心的分布式运行时系统,和加速机器学习工作负载的AI软件库。
- Kornia:基于PyTorch的可微分计算机视觉软件库[263]。
- spaCy:用Python和Cython开发的工业级实力的自然语言处理软件库[264]。
- Argos Translate:基于OpenNMT的离线神经机器翻译软件库[265]。
- Stable Diffusion:用Python开发的深度学习文本到图像生成模型[266],基于了CUDA、PyTorch、VAE、U-Net和OpenAI的CLIP[267],其代码和模型权重已公开发布,可以在大多数配备有适度GPU的消费类计算机硬件上运行。
- Transformers:为下载和训练前沿的预训练模型提供API和工具[268],由Hugging Face开发,支持在PyTorch、TensorFlow和JAX之间的框架互操作性。
- Gradio:它是一个Python库,允许快速创建和分享用于机器学习模型、API或任何任意Python函数的Web应用程序。使用Gradio,可以构建交互式用户界面,与各种机器学习框架兼容。还可以使用Gradio以交互方式调试模型、从用户获取反馈,并通过自动生成的可共享链接轻松部署模型。[269][270]
- LangChain:它是一个应用框架,旨在简化使用大型语言模型的应用程序。作为一个语言模型集成框架,LangChain的用例包括文档分析和总结摘要, 代码分析和聊天机器人。[271] LangChain提供了一个标准接口,用于将不同的语言模型(LLM)连接在一起,以及与其他工具和数据源的集成。
社群流行
[编辑]自从2003年,Python始终排行于TIOBE编程社区索引前十最流行编程语言,在2021年10月它首次达到了第一名最流行语言(居于C和Java之前)[272],并被选为2007年、2010年、2018年、2020年和2021年的年度编程语言[272]。它有如下著名的社群:
- PyCon:各地社群舉辦的會議,通常每年舉辦。各社群在會議中討論Python相關的議題。
- Python Discord:参与者众多的Python社区[273]。
- PyLadies:由女性社群發起的社群,主要注重於發展Python的女性程式設計社群。
- Django Girls:使用Django網頁設計框架,推廣使用Python進行網頁設計的技術。
影響的语言
[编辑]Python的设计和哲学已经影响了很多其他编程语言:
- Boo:使用了缩进、类似的语法和类似的对象模型[274]。
- Cobra:使用了缩进和类似的语法[275]。
- Coconut:在Python语法之上增加了用于函数式编程的新特征的Python变体[276]。
- CoffeeScript:有受Python启发的语法。
- ECMAScript/JavaScript:从Python借鉴了迭代器和生成器[277]。
- GDScript:内置于Godot游戏引擎的非常类似Python的脚本语言[25]。
- Genie:基于Vala编译器的具有近似Python语法的语言。
- Go:其设计原则受到了Python的可读性与易用性的启发[27],享有相同风格的数组分片语法。
- Groovy:受到Python等动态类型语言的影响[278]。
- Julia:在表达高级数值计算的方式和支持通用编程上借鉴了Python等语言[30]。
- Kotlin:融合了Python和Java特征,极小化了样板代码而增加了开发效率[279]。
- Mojo:基于MLIR编译框架并设计为Python语言的超集[280]。
- Nim:使用缩进和类似的语法[281]。
- Ruby:主要从Python等语言中借鉴了特征[32]。
- Starlark:用在Bazel软件中有受Python启发语法的语言[33]。
- Swift:有受Python启发的语法[34]。
代码示例
[编辑]- ^ 縮排示例:
def is_even(a: int) -> bool: """确定数a是否是偶数.""" if a % 2 == 0: print('偶数!') return True print('奇数!') return False # 参数比后续部份多一层缩进 def long_function_name( var_one, var_two, var_three, var_four): # 可选的圆括号内后续行多一层缩进 if (this_is_first_thing and that_is_second_thing): do_something() # 可选的圆括号内后续行不额外缩进 elif (this_is_third_thing and that_is_fourth_thing): do_something_different() # 参数相对行首缩进一层 spam = long_function_name( arg_one, arg_two, arg_three, arg_four) # 参数按开括号界定垂直对齐 eggs = long_function_name(arg_one, arg_two, arg_three, arg_four) # 可选的闭括号位置 my_list = [ 1, 2, 3, 4, 5, 6, ] # 可选的闭括号位置 my_set = { 1, 2, 3, 4, 5, 6, }
- ^ 采用了并行赋值的斐波那契数列函数示例:
def fib(n): # 写出从第0项到第n项的Fibonacci系列 a, b, i = 0, 1, 0 while i <= n: print(a, end=' ') a, b, i = b, a+b, i+1 print()
- ^ 产生素数的惰性生成器的示例:
from itertools import count def generate_primes(stop_at=0): if stop_at != 1: primes = [2] yield 2 for n in count(3, 2): if 0 < stop_at < n: return # 引发StopIteration例外 composite = False for p in primes: if not n % p: composite = True break elif p ** 2 > n: break if not composite: primes.append(n) yield n
上述函数的隐式迭代用例:
for i in generate_primes(): # 迭代于100以内所有素数上 if i > 100: break print(i)
在生成器表达式中使用上述函数,定义了一个惰性的、巨大而并非无限的搜集的示例:
from itertools import islice primes_under_million = (i for i in generate_primes() if i < 1000000) two_thousandth_prime = islice(primes_under_million, 1999, 2000) print(next(two_thousandth_prime))
- ^ 用生成器模拟协程示例:
def produce(n): try: for item in range(n): print(f'producing item {item} ->') yield item except GeneratorExit: return def consume(): item = None try: while True: item = yield item print(f'consuming item {item} <-') except GeneratorExit: return def main(): r = [] t1 = produce(10) t2 = consume() try: next(t2) while True: p = next(t1) r += [t2.send(p)] except StopIteration: t2.close() print(f'result items: {r}') main()
- ^ 遵循EAFP(请求原谅比获得许可更容易)风格的例外处理示例:
f = None try: f = open("aFileName", mode="w") f.write(could_make_error()) # 不存在could_make_error()则产生错误 except IOError as error: print(error) print("不能打开文件") except: # 捕获所有例外 print("未预期的错误") else: # 在没有出现例外时执行 print("文件写入完全成功") finally: # 清除行动,总是执行 if f: f.close()
- ^ 使用
with
将文件作为资源来管理的示例:from contextlib import contextmanager @contextmanager def opened(filename, mode="r"): try: f = open(filename, mode) except IOError as error: print(error) yield None else: try: yield f finally: f.close() with opened("aFileName", mode="w") as f: try: f.write(could_make_error()) # 不存在could_make_error()则产生错误 except AttributeError: print("不能打开文件") except: # 捕获所有例外 print("未预期的错误") else: # 在没有出现例外时执行 print("文件写入完全成功")
- ^ 原生的协程示例:
import asyncio import random async def produce(queue, n): for item in range(n): # 生产一个项目,使用sleep模拟I/O操作 print(f'producing item {item} ->') await asyncio.sleep(random.random()) # 将项目放入队列 await queue.put(item) # 指示生产完毕 await queue.put(None) async def consume(queue): while True: # 等待来自生产者的项目 item = await queue.get() if item is None: break # 消费这个项目,使用sleep模拟I/O操作 print(f'consuming item {item} <-') await asyncio.sleep(random.random()) async def main(): queue = asyncio.Queue() task1 = asyncio.create_task(produce(queue, 10)) task2 = asyncio.create_task(consume(queue)) await task1 await task2 asyncio.run(main())
- ^ 局部变量示例:
>>> def spam(): ... print(a) ... >>> a = 10 >>> spam() 10 >>> def spam(): ... a = 100 ... print(a) ... >>> spam() 100 >>> a 10 >>> def spam(): ... a *= 10 ... print(a) ... >>> spam() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in spam UnboundLocalError: cannot access local variable 'a' where it is not associated with a value
- ^ 全局变量示例:
>>> def spam(): ... global a ... a *= 10 ... print(a) ... >>> a = 10 >>> spam() 100 >>> a 100 >>> def spam(): ... def eggs(): ... print(a) ... global a ... eggs() ... >>> a = 10 >>> spam() 10 >>> def spam(): ... def eggs(): ... a *= 10 ... print(a) ... global a ... eggs() ... >>> spam() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in spam File "<stdin>", line 3, in eggs UnboundLocalError: cannot access local variable 'a' where it is not associated with a value
- ^ 非局部变量示例:
>>> def spam(): ... def eggs(): ... nonlocal a ... a *= 10 ... print(a) ... a = 10 ... eggs() ... >>> spam() 100 >>> def spam(): ... def eggs(): ... nonlocal a ... a *= 10 ... print(a) ... global a ... eggs() ... File "<stdin>", line 3 SyntaxError: no binding for nonlocal 'a' found
- ^ 序列解包、可迭代解包和字典解包示例:
>>> a = [1, 2, 3]; b = [4, 5] >>> i, j, k = a >>> print(i, j, k) 1 2 3 >>> c = [*a, b] >>> c [1, 2, 3, [4, 5]] >>> d = {*a, *b} >>> d {1, 2, 3, 4, 5} >>> e = (*a, *b) >>> e (1, 2, 3, 4, 5) >>> f = {'as':1, 'bs':2 }; g = {'cs':3, 'ds':4} >>> h = {**f, **g} >>> h {'as': 1, 'bs': 2, 'cs': 3, 'ds': 4}
- ^ 列表的推导式示例。比如:
>>> [x + 3 for x in range(4)] [3, 4, 5, 6]
快速排序算法可以优雅的(尽管不高效的)使用列表推导式表达为:
def qsort(L): if L == []: return [] pivot = L[0] return (qsort([x for x in L[1:] if x < pivot]) + [pivot] + qsort([x for x in L[1:] if x >= pivot]))
- ^ 生成器表达式示例。比如:
>>> sum(x * x for x in range(10)) 285 >>> dict((n, n*n) for n in range(5)) {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} >>> set(n*n for n in range(5)) {0, 1, 4, 9, 16}
- ^ 字典推导式
{expr1: expr2 for k, v in d}
,等价于:result={} for k, v in d.items(): result[expr1]=expr2 return result
>>> {x: x + 3 for x in range(4)} {0: 3, 1: 4, 2: 5, 3: 6}
集合推导式
{expr1 for x in stuff}
,等价于:result = set() for x in stuff: result.add(expr1) return result
>>> {x + 3 for x in range(4)} {3, 4, 5, 6}
- ^ 下面几个判断语句为真,表示列表分片结果符合预期:
>>> nums = [1, 3, 5, 7, 8, 13, 20] >>> nums[2:5] == [5, 7, 8] #从下标为2的元素切割到下标为5的元素,但不包含下标为5的元素。 True >>> nums[1:] == [3, 5, 7, 8, 13, 20] #切割到最后一个元素。 True >>> nums[:-3] == [1, 3, 5, 7] #从最开始的元素一直切割到倒数第3个元素。 True >>> nums[:] == [1, 3, 5, 7, 8, 13, 20] #返回所有元素。改变新的列表不会影响到nums。 True >>> nums[1:5:2] == [3, 7] #从下标为1的元素切割到下标为5的元素,但不包含下标为5的元素,且步长为2。 True
- ^ 匿名函数示例:
>>> from functools import reduce >>> reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) 15 >>> fac = lambda n: (1 if n<2 else n*fac(n-1)) >>> fac(5) 120 >>> [*map(fac, [1, 2, 3, 4, 5])] [1, 2, 6, 24, 120]
不动点组合子示例:
>>> Y = lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args))) >>> fac = lambda f: lambda n: (1 if n<2 else n*f(n-1)) >>> Y(fac)(5) 120 >>> fib = lambda f: lambda n: 0 if n == 0 else (1 if n == 1 else f(n-1) + f(n-2)) >>> Y(fib)(6) 8 >>> [*map((lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args))))(lambda f: lambda n: (1 if n<2 else n*f(n-1))), [1, 2, 3, 4, 5])] [1, 2, 6, 24, 120]
上述Y组合子代码源出自Rosetta Code. [2020-10-21]. (原始内容存档于2021-01-11).其原理可参见Equational derivations of the Y combinator and Church encodings in Python. [2020-10-21]. (原始内容存档于2020-11-12).
- ^ 多行字符串文字带有字符串插值(使用了
format
方法)的示例:print("""亲爱的{recipient}, 我希望你离开Sunnydale并永不返回. 不是很爱你的, {sender} """.format(sender="吸血鬼猎人Buffy", recipient="Spike"))
- ^ 原始字符串的示例:
>>> # Windows路径,即使是原始字符串也不能结束于反斜杠 >>> r"C:\Spam\Eggs\Ham\" File "<stdin>", line 1 r"C:\Spam\Eggs\Ham\" ^ SyntaxError: EOL while scanning string literal >>> dos_path = r"C:\Spam\Eggs\Ham\ " # 通过增加尾随的空格 >>> dos_path.rstrip() # 并接着移除它来避免错误 'C:\\Spam\\Eggs\\Ham\\' >>> quoted_dos_path = r'"{}"'.format(dos_path) >>> quoted_dos_path '"C:\\Spam\\Eggs\\Ham\\ "' >>> # 匹配具有可能的反斜杠引述的引述字符串的正则表达式 >>> import re >>> re.match(r'"(([^"\\]|\\.)*)"', quoted_dos_path).group(1).rstrip() 'C:\\Spam\\Eggs\\Ham\\' >>> code = 'spam(2, eggs)' >>> # 反转有二个参数的函数调用的两个实际参数 >>> re.sub(r'\(([^,]*),\s*([^,]*)\)', r'(\2, \1)', code) 'spam(eggs, 2)' >>> # 注意如果实际参数中有圆括号或逗号则上例无效。
- ^ 字符串文字串接示例:
>>> print("hello " 'world') hello world >>> str1="hello "; str2='world' >>> print(str1 + str2) hello world
- ^ 格式化字符串的示例,例如下列命令行
echo
命令:num="3"; printer="HP Laserjet" echo "I just printed ${num} pages to the printer ${printer}"
等价于如下Python中的任何一种
print
函数调用:num = 3; printer="HP Laserjet" print(f"I just printed {num} pages to the printer {printer}") print("I just printed {} pages to the printer {}".format(num, printer)) print("I just printed {0} pages to the printer {1}".format(num, printer)) print("I just printed {num} pages to the printer {printer}".format(num=num, printer=printer)) print("I just printed %s pages to the printer %s" % (num, printer)) print("I just printed %(num)s pages to the printer %(printer)s" % {"num": num, "printer": printer})
- ^ 词法闭包的例子:
def f(x): def g(y): return x + y return g # 返回一个闭包。 h = lambda x: lambda y: x + y # 将指定闭包赋值给变量。 a = f(1) b = h(1) c = f(2) # 使用存储在变量中的闭包。 assert a(5) == 6 assert b(5) == 6 assert c(5) == 7 # 使用闭包而不事先把它们绑定到变量。 assert f(1)(5) == 6 # f(1)是个闭包。 assert h(1)(5) == 6 # h(1)是个闭包。 assert f(2)(5) == 7 # f(2)是个闭包。
- ^ 函数的形式参数缺省值的持久性示例:
>>> def f(a, L=[]): ... L.append(a) ... return L ... >>> print(f(1)) [1] >>> print(f(2)) [1, 2] >>> print(f(3)) [1, 2, 3]
- ^ 函数的形实参数二者结合示例。例如:
>>> def spam(a): ... a.append('LovelySpam') ... >>> def eggs(b): ... b=100 #实际上是重新绑定了另一个整型对象100 ... >>> a=[] >>> b=10 >>> spam(a) >>> eggs(b) >>> print(a) ['LovelySpam'] >>> print(b) 10
- ^ 函数的形式参数缺省值的定义示例:
>>> from inspect import getfullargspec >>> def func(p1, /, p2, p3="x", *, p4): pass ... >>> getfullargspec(func) FullArgSpec(args=['p1', 'p2', 'p3'], varargs=None, varkw=None, defaults=('x',), kwonlyargs=['p4'], kwonlydefaults=None, annotations={})
- ^ 函数的可变参数的定义示例:
>>> from inspect import getfullargspec >>> def func(p1, /, p2, *args, p3, **kwargs): pass ... >>> getfullargspec(func) FullArgSpec(args=['p1', 'p2'], varargs='args', varkw='kwargs', defaults=None, kwonlyargs=['p3'], kwonlydefaults=None, annotations={})
- ^ 定义修饰器的示例:
def viking_chorus(myfunc): def inner_func(*args, **kwargs): for i in range(3): myfunc(*args, **kwargs) return inner_func
调用修饰器的示例:
@viking_chorus def menu_item(*args): print(", ".join(args)+", and spam")
等价于:
def menu_item(*args): print(", ".join(args)+", and spam") menu_item = viking_chorus(menu_item)
viking_chorus
修饰后的menu_item
将原来定义运行3次:>>> menu_item("egg","bacon") egg, bacon, and spam egg, bacon, and spam egg, bacon, and spam
- ^ 修饰器工厂示例,这里的
favourite_colour
接受一个实际参数,并返回一个修饰器:def favourite_colour(colour): def decorator(func): def wrapper(*args, **kwargs): print(f"My favourite colour is {colour}.") func(*args, **kwargs) return wrapper return decorator def invincible(func): def wrapper(*args, **kwargs): print("I'm invincible!") func(*args, **kwargs) return wrapper
使用毗连的修饰符链接修饰器示例:
@invincible @favourite_colour("blue") def black_knight(): print("None shall pass.")
使用中间变量链接修饰器示例:
blue_decorator = favourite_colour("blue") decorated_by_blue = blue_decorator(black_knight) black_knight = invincible(decorated_by_blue)
它们等价于:
black_knight = invincible(favourite_colour("blue")(black_knight))
black_knight()结果为:
>>> black_knight() I'm invincible! My favourite colour is blue. None shall pass.
- ^ 调用函数使用帮助信息示例。比如:
>>> def randint(a, b): ... "Return random integer in range [a, b], including both end points." ... >>> help(randint) Help on function randint in module __main__: randint(a, b) Return random integer in range [a, b], including both end points.
- ^ 如下这样给参数增加类型标注的提示信息:
>>> def greeting(name: str) -> str: ... return 'Hello ' + name ... >>> greeting.__annotations__ {'name': <class 'str'>, 'return': <class 'str'>}
- ^ 对象的方法示例:
>>> class Fish(object): ... hungry = True ... def eat(self, food): ... if food is not None: ... self.hungry=False ... >>> def status(self): ... print("Hungray!" if self.hungry else "Not hungray!") ... >>> e = Fish() >>> status(e) Hungray! >>> Fish.hungry = False >>> from types import MethodType >>> e.status = MethodType(status, e) >>> e.status() Not hungray! >>> Fish.hungry = True >>> Fish.status = status >>> f = Fish() >>> Fish.status(f) Hungray! >>> f.eat("earthworm") >>> f.status() Not hungray!
- ^ 特殊方法和子类调用超类方法的例子:
>>> class Thought(object): ... cls_name = "类型Thought" ... def __init_subclass__(cls): ... cls.cls_name = "类型Thought的子类型" ... def __init__(self, *args, **kwargs): ... print(f"我是{type(self).cls_name}的新对象!") ... if len(args) != 0 or len(kwargs) != 0: ... print(f"init: nargs={len(args)}, nkwargs={len(kwargs)}") ... self.notion = "我觉得我在平行宇宙中把车停歪了." ... def message(self, *args): ... print(self.notion) ... if len(args) != 0: ... print("\n".join(args)) ... >>> class Advice(Thought): ... def message(self): ... super().message("警告: 日历里的日期比它们看起来更近!") ... >>> t = Thought() 我是类型Thought的新对象! >>> t.message() 我觉得我在平行宇宙中把车停歪了. >>> a = Advice() 我是类型Thought的子类型的新对象! >>> a.message() 我觉得我在平行宇宙中把车停歪了. 警告: 日历里的日期比它们看起来更近! >>> # 内省一下: >>> [*super.__dict__] ['__new__', '__repr__', '__getattribute__', '__get__', '__init__', '__thisclass__', '__self__', '__self_class__', '__doc__'] >>> [*super(Advice).__thisclass__.__dict__] ['__module__', 'message', '__doc__', 'cls_name'] >>> super(Advice).__thisclass__.__dict__['cls_name'] '类型Thought的子类型' >>> [*super(Advice, a).__self__.__dict__] ['notion'] >>> super(Advice, a).__self_class__.__dict__['cls_name'] '类型Thought的子类型' >>> super(Advice, a).message() 我觉得我在平行宇宙中把车停歪了. >>> super(Advice).__get__(a).message() 我觉得我在平行宇宙中把车停歪了.
- ^ 在类中采用数据描述器的示例:
>>> class RevealAccess: ... """正常的设置和返回值的数据描述器, ... 它还打印记录这次访问的一个消息。 ... """ ... def __init__(self, initval=None, name='var'): ... self.val = initval ... self.name = name ... def __get__(self, obj, objtype): ... print('Retrieving', self.name) ... return self.val ... def __set__(self, obj, val): ... print('Updating', self.name) ... self.val = val ... >>> class MyClass: ... x = RevealAccess(10, 'var "x"') ... y = 5 ... >>> m = MyClass() >>> m.x Retrieving var "x" 10 >>> vars(m) {} >>> MyClass.__dict__['x'].val 10 >>> m.x = 20 Updating var "x" >>> vars(m) {} >>> MyClass.__dict__['x'].val 20 >>> m.y 5 >>> vars(m) {} >>> m.y = 5 >>> vars(m) {'y': 5}
- ^ 特殊方法、类方法和静态方法(
__new__()
)示例:>>> from weakref import WeakValueDictionary >>> class D: ... _template = {} ... _obj_dict = WeakValueDictionary() ... def __new__(cls, *args, **kwargs): ... obj = super(D, cls).__new__(cls) ... cls._obj_dict[id(obj)] = obj ... return obj ... @classmethod ... def load(cls, dict): ... cls._template.update(dict) ... @classmethod ... def create(cls, *args, **kwargs): ... return cls(cls._template, *args, **kwargs) ... @classmethod ... def count(cls): ... return len(cls._obj_dict) ... def __init__(self, dict={}, /, *args, **kwargs): ... self.__dict__.update(dict) ... self.__dict__.update(kwargs) ... def __call__(self, *args, **kwargs): ... self.__dict__.update(kwargs) ... return self.__dict__.copy() ... def __len__(self): ... return len(self.__dict__) ... def __getitem__(self, key): ... return self.__dict__[key] ... def __setitem__(self, key, value): ... self.__dict__[key] = value ... >>> a = {'ak': 1, 'bk': 2, 'ck': 3} >>> d = D(a, dk=4) >>> d() {'ak': 1, 'bk': 2, 'ck': 3, 'dk': 4} >>> D.load(a) >>> e = D.create(ck=4) >>> e() {'ak': 1, 'bk': 2, 'ck': 4} >>> f = D(ak=1, bk=2) >>> f(ck=3) {'ak': 1, 'bk': 2, 'ck': 3} >>> f['ak'] 1 >>> f['ak'] = 5 >>> f() {'ak': 5, 'bk': 2, 'ck': 3} >>> len(f) 3 >>> D.count() 3 >>> del f >>> D.count() 2 >>> d.__weakref__ in D._obj_dict.valuerefs() True
- ^ 在类中调用
property()
的例子:>>> class C: ... def __init__(self): ... self.__x = None ... def getx(self): ... return self.__x ... def setx(self, value): ... self.__x = value ... def delx(self): ... del self.__x ... x = property(getx, setx, delx, "I'm the 'x' property.") ... >>> c = C() >>> vars(c) {'_C__x': None} >>> {*C.__dict__} {'__init__', 'setx', '__weakref__', 'delx', 'x', 'getx', '__doc__', '__module__', '__dict__'}
上述代码可以采用修饰符进一步的书写为:
>>> class C: ... def __init__(self): ... self.__x = None ... @property ... def x(self): ... """I'm the 'x' property.""" ... return self.__x ... @x.setter ... def x(self, value): ... self.__x = value ... @x.deleter ... def x(self): ... del self.__x ... >>> c = C() >>> vars(c) {'_C__x': None} >>> {*C.__dict__} {'__init__', '__weakref__', 'x', '__doc__', '__module__', '__dict__'}
- ^ 建立列表的特殊语法示例:
a_list = [1, 2, 3, 'a dog']
采用正常的对象创建方式的示例:
a_second_list = list() a_second_list.append(4) a_second_list.append(5)
建立元组的特殊语法示例:
a_tuple = 1, 2, 3, 'four'
建立集合的特殊语法示例:
some_set = {0, (), False}
建立字典的特殊语法示例:
a_dictionary = {'key 1': 'value 1', 2: 3, 4: []}
- ^ 两个类及元类等的实例关系(蓝色连接)与继承关系(绿色连接)示意图:
r = object c = type class M(c): pass class A(metaclass=M): pass class B(A): pass b = B()
>>> type(b) <class '__main__.B'> >>> print(type(B), B.__bases__) <class '__main__.M'> (<class '__main__.A'>,) >>> print(type(A), A.__bases__) <class '__main__.M'> (<class 'object'>,) >>> print(type(M), M.__bases__) <class 'type'> (<class 'type'>,) >>> print(type(c), c.__bases__) <class 'type'> (<class 'object'>,) >>> print(type(r), r.__bases__) <class 'type'> ()
- ^ 数学运算示例。比如:
>>> def mean(seq): ... return sum(seq) / len(seq) ... >>> mean([3, 4]) 3.5 >>> import math >>> print(math.sin(math.pi/2)) 1.0
註釋
[编辑]- ^ 1.0 1.1 GitHub repository of Python 0.9.1 source. [2023-02-25]. (原始内容存档于2023-03-05).
HISTORY. Python source distribution. Python Foundation. [2017-11-23]. (原始内容存档于2017-12-01). - ^ "Python 3.13 released"; 检索日期: 2024年10月7日; 作品或名稱使用語言: 英語; 出版日期: 2024年10月7日; 宣传物: LWN.net.
- ^ Python 3.13.0 (final) released. 2024年10月7日 [2024年10月8日] (英語).
- ^ "Python 3.13 Debuts With New Interactive Interpreter & Experimental JIT"; 检索日期: 2024年10月8日; 作品或名稱使用語言: 英語; 出版日期: 2024年10月7日; 宣传物: Phoronix.
- ^ "Python 3.14 Alpha 1 Released With Early Changes"; 检索日期: 2024年10月16日; 作品或名稱使用語言: 英語; 出版日期: 2024年10月15日; 宣传物: Phoronix.
- ^ Python 3.14.0 alpha 1 is now available. 2024年10月15日 [2024年10月16日] (英語).
- ^ 7.0 7.1 Glossary — duck-typing. [2023-06-28]. (原始内容存档于2020-06-25).
- ^ Why is Python a dynamic language and also a strongly typed language - Python Wiki. wiki.python.org. [2021-01-27]. (原始内容存档于2021-03-14).
- ^ 9.0 9.1 PEP 483 – The Theory of Type Hints. [2023-03-16]. (原始内容存档于2023-03-26).
- ^ File extension .pyo was removed in Python 3.5. See PEP 0488 (页面存档备份,存于互联网档案馆)
- ^ Holth, Moore. PEP 0441 -- Improving Python ZIP Application Support. 2014-03-30 [2015-11-12]. (原始内容存档于2018-12-26).
- ^ 12.0 12.1 12.2 Why was Python created in the first place?. Python FAQ. [2007-03-22]. (原始内容存档于2008-02-23).
- ^ Andrew Kuchling, Guido van Rossum. LJ Interviews Guido van Rossum. November 1, 1998 [2023-03-21]. (原始内容存档于2023-03-30).
String slicing came from Algol-68 and Icon.
- ^ 14.0 14.1 The Python Standard Library - Functional Programming Modules - itertools — Functions creating iterators for efficient looping. [2020-04-22]. (原始内容存档于2020-06-14).
- ^ van Rossum, Guido. An Introduction to Python for UNIX/C Programmers. Proceedings of the NLUUG Najaarsconferentie (Dutch UNIX Users Group). 1993 [2021-03-14]. (原始内容存档于2013-06-17).
even though the design of C is far from ideal, its influence on Python is considerable.
- ^ 16.0 16.1 The Python Tutorial - 9. Classes. [20 February 2012]. (原始内容存档于2012-10-23).
Compared with other programming languages, Python’s class mechanism adds classes with a minimum of new syntax and semantics. It is a mixture of the class mechanisms found in C++ and Modula-3.
- ^ Fredrik Lundh. Python-list mailing list - passing by refference. [2023-03-06]. (原始内容存档于2023-03-06).
replace "CLU" with "Python", "record" with "instance", and "procedure" with "function or method", and you get a pretty accurate description of Python's object model.
- ^ 18.0 18.1 Simionato, Michele. The Python 2.3 Method Resolution Order. Python Software Foundation. [2021-03-14]. (原始内容存档于2020-08-20).
The C3 method itself has nothing to do with Python, since it was invented by people working on Dylan and it is described in a paper intended for lispers.
- ^ Kuchling, A. M. Functional Programming HOWTO. Python v2.7.2 documentation. Python Software Foundation. [9 February 2012]. (原始内容存档于2012-10-24).
- ^ 20.0 20.1 20.2 Guido van Rossum. Python Reference Manual - Version 1.2 (PDF). CWI Report CS-R9525. May 1995 [2023-03-04]. (原始内容存档 (PDF)于2023-03-05).
Python is a simple, yet powerful, interpreted programming language that bridges the gap between C and shell programming, and is thus ideally suited for "throw-away programming" and rapid prototyping. Its syntax is put together from constructs borrowed from a variety of other languages; most prominent are influences from ABC, C, Modula-3 and Icon.
The Python interpreter is easily extended with new functions and data types implemented in C. Python is also suitable as an extension language for highly customizable C applications such as editors or window managers. - ^ Smith, Kevin D.; Jewett, Jim J.; Montanaro, Skip; Baxter, Anthony. PEP 318 – Decorators for Functions and Methods. Python Enhancement Proposals. Python Software Foundation. 2 September 2004 [24 February 2012]. (原始内容存档于2020-06-03).
- ^ More Control Flow Tools. Python 3 documentation. Python Software Foundation. [24 July 2015]. (原始内容存档于2016-06-04).
- ^ re — Regular expression operations. docs.python.org. [2022-09-06]. (原始内容存档于2018-07-18).
This module provides regular expression matching operations similar to those found in Perl.
- ^ CoffeeScript. coffeescript.org. [2021-03-14]. (原始内容存档于2020-06-12).
- ^ 25.0 25.1 FAQ: What is GDScript and why should I use it?. [2020-09-13]. (原始内容存档于2020-05-19).
- ^ The Genie Programming Language Tutorial. [28 February 2020]. (原始内容存档于2020-06-01).
- ^ 27.0 27.1 Frequently Asked Questions (FAQ) - The Go Programming Language. The Go Programming Language. [February 26, 2016].
- ^ Perl and Python influences in JavaScript. www.2ality.com. 24 February 2013 [15 May 2015]. (原始内容存档于2018-12-26).
- ^ Rauschmayer, Axel. Chapter 3: The Nature of JavaScript; Influences. O'Reilly, Speaking JavaScript. [15 May 2015]. (原始内容存档于2018-12-26).
- ^ 30.0 30.1 Home · The Julia Language. docs.julialang.org. [2018-08-15]. (原始内容存档于11 January 2021) (英语).
- ^ Krill, Paul. Mojo language marries Python and MLIR for AI development. InfoWorld. 2023-05-04 [2023-05-05]. (原始内容存档于5 May 2023) (英语).
- ^ 32.0 32.1 Bini, Ola. Practical JRuby on Rails Web 2.0 Projects: Bringing Ruby on Rails to Java. Berkeley: APress. 2007: 3. ISBN 978-1-59059-881-8.
It draws primarily on features from Perl, Smalltalk, Python, Lisp, Dylan, and CLU.
- ^ 33.0 33.1 Starlark Language. [25 May 2019]. (原始内容存档于2020-06-15).
- ^ 34.0 34.1 Lattner, Chris. Chris Lattner's Homepage. Chris Lattner. 3 June 2014 [3 June 2014]. (原始内容存档于2018-12-25).
Of course, it also greatly benefited from the experiences hard-won by many other languages in the field, drawing ideas from Objective-C, Rust, Haskell, Ruby, Python, C#, CLU, and far too many others to list.
- ^ 彼德·諾米格. Python for Lisp Programmers. [2020-04-21]. (原始内容存档于2020-06-14).
Python can be seen as a dialect of Lisp with "traditional" syntax (what Lisp people call "infix" or "m-lisp" syntax).
- ^ Rossum, Guido Van. The History of Python: A Brief Timeline of Python. The History of Python. 2009-01-20 [2021-03-05]. (原始内容存档于5 June 2020).
- ^ Peterson, Benjamin. Python Insider: Python 2.7.18, the last release of Python 2. Python Insider. 20 April 2020 [27 April 2020]. (原始内容存档于26 April 2020).
- ^ Stack Overflow Developer Survey 2020. Stack Overflow. [2021-03-05]. (原始内容存档于2 March 2021).
- ^ The State of Developer Ecosystem in 2020 Infographic. JetBrains: Developer Tools for Professionals and Teams. [2021-03-05]. (原始内容存档于1 March 2021) (英语).
- ^ index | TIOBE - The Software Quality Company. www.tiobe.com. [2021-02-02]. (原始内容存档于25 February 2018).
Python has won the TIOBE programming language of the year award! This is for the fourth time in the history, which is a record! The title is awarded to the programming language that has gained most popularity in one year.
- ^ PYPL PopularitY of Programming Language index. pypl.github.io. [2021-03-26]. (原始内容存档于14 March 2017) (英语).
- ^ Guido van Rossum - Resume. [2022-10-12]. (原始内容存档于2022-12-21).
- ^ amoeba operating system. [2023-02-25]. (原始内容存档于2023-03-05).
- ^ Whetting Your Appetite. The Python Tutorial. Python Software Foundation. [2012-02-20]. (原始内容存档于2012-10-26).
- ^ Benevolent dictator for life. Linux Format. 2005-02-01 [2007-11-01]. (原始内容存档于2006-10-01).
- ^ Transfer of power. [2020-11-29]. (原始内容存档于2018-07-12).
- ^ PEP 8100. python. Python Software Foundation. [2019-05-04]. (原始内容存档于2020-06-04).
- ^ Steering Council nomination: Guido van Rossum (2020 term). [2020-10-11]. (原始内容存档于2019-12-29).
- ^ The Making of Python. Artima Developer. [2007-03-22]. (原始内容存档于2016-09-01).
- ^ Older source releases (1.0.1 - 1.6). [2023-03-05]. (原始内容存档于2023-03-05).
- ^ HISTORY. [2020-09-12]. (原始内容存档于2017-12-01).
Lambda expressions are particularly useful in combination with map(), filter() and reduce(), described below. Thanks to Amrit Prem for submitting this code (as well as map(), filter(), reduce() and xrange())!
- ^ LJ #37: Python 1.4 Update. [2007-04-29]. (原始内容存档于2007-05-01).
- ^ Kuchling, A. M.; Zadka, Moshe. What's New in Python 2.0. Python Software Foundation. 2000-10-16 [2012-02-11]. (原始内容存档于2012-10-23).
- ^ Hylton, Jeremy. PEP 227 - Statically Nested Scopes. 2000-11-01 [2007-03-22]. (原始内容存档于2007-03-29).
- ^ 55.0 55.1 55.2 Guido van Rossum. Unifying types and classes in Python 2.2. [2020-09-26]. (原始内容存档于2019-09-28).
- ^ What’s New in Python 2.2 - PEP 234: Iterators. [2020-10-21]. (原始内容存档于2021-02-07).
- ^ What’s New in Python 2.2 - PEP 255: Simple Generators. [2020-10-21]. (原始内容存档于2021-02-07).
- ^ What’s New in Python 2.2 - Descriptors. [2020-10-21]. (原始内容存档于2021-02-07).
- ^ 59.0 59.1 59.2 What’s New in Python 2.4 - PEP 318: Decorators for Functions and Methods. [2020-10-21]. (原始内容存档于2021-02-07).
- ^ What’s New in Python 2.5 - PEP 343: The ‘with’ statement. [2020-10-21]. (原始内容存档于2021-02-07).
- ^ PEP 339 – Design of the CPython Compiler. 2005 [2023-03-06]. (原始内容存档于2023-03-06).
- ^ Guido van Rossum. What’s New In Python 3.0. [2023-02-18]. (原始内容存档于2012-11-02).
- ^ What’s New In Python 3.4 - asyncio. [2023-02-22]. (原始内容存档于2023-06-13).
- ^ What’s New In Python 3.5 - PEP 484 - Type Hints. [2023-02-25]. (原始内容存档于2016-06-18).