Python(英語發音:/ˈpaɪθən/;英語發音:/ˈpaɪθɑːn/),是一种广泛使用的解释型、高级和通用的编程语言。Python支持多种编程范型,包括结构化、过程式、反射式、面向对象和函数式编程。它拥有动态类型系统和垃圾回收功能,能够自动管理内存使用,并且其本身拥有一个巨大而广泛的标准库。它的语言结构以及面向对象的方法,旨在帮助程序员为小型的和大型的项目编写逻辑清晰的代码。
吉多·范罗苏姆于1980年代后期开始研发Python,作为ABC语言的后继者,它也可以被视为采用了叫做M-表达式的中缀表示法的一种LISP方言。吉多·范罗苏姆于1991年首次发布 Python 0.9.0。Python 2.0于2000 年发布并引入了新功能。Python 3.0于2008年发布,它是该语言的主要修订版,并非完全向后兼容。Python 2于2020年随2.7.18版停止支持。
Python的设计哲学,强调代码的可读性和简洁的语法,尤其是使用空格缩进来划分代码块。相比於C语言或Java,Python让开发者能够用更少的代码表达想法。
Python解释器本身几乎可以在所有的操作系统中运行,它的官方直譯器CPython是用C语言编写的。Python是一個由社群驱动的自由软件,目前由Python软件基金会管理。Python是最受欢迎的编程语言之一。
== 歷史 ==
Python的創始人吉多·范羅蘇姆,在1982年至1995年间,参与了荷兰数学和计算机科学研究学会多个项目的工作。1989年的聖誕節期間,他決心開發一個新的腳本解釋程式,作為ABC語言的後繼者,并且用它替代Unix shell和C语言来进行系统管理,担负与Amoeba操作系统之间的交互操作并进行例外处理。他是BBC電視劇《Monty Python的飛行馬戲團》的爱好者,所以选取了Python作为这个编程语言的名字。范羅蘇姆作为Python的主要開發者,独自担负这个项目的发展决策者职责,直到2018年7月12日,他宣布从終身仁慈獨裁者(BDFL)的职位上“永久休假”。他在2019年1月至11月参与了第一届五人掌控委员会继续领导项目发展。
在1991年2月,范羅蘇姆在alt.sources上发布了最初代码(标记为版本0.9.0),这时就已经存在了带继承的类、例外处理、函数和核心类型list、dict、str等。在这个最初发行中就有了从Modula-3引进的模块系统,和例外处理机制。在1994年1月,Python版本1.0发布,其主要新特征是由Amrit Prem提供的函数式编程工具lambda、map、filter和reduce。受Modula-3启发,Python 1.1介入了缺省参数值,Python 1.3介入了关键字参数。Python 1.4介入了对复数的内建支持,还包含了采取名字修饰的一种基本形式的数据隐藏。
在2000年10月,Python 2.0發布,它从函数式编程语言Haskell中引进了列表推导式,并且支持了Unicode,还向垃圾回收系统增加了环检测算法。Python 2.1支持了静态嵌套作用域和闭包。Python 2.2进行了重大革新,将Python中用C语言写成的类型,和用Python语言写成的类,统一成在同一个层级中,使得Python的对象模型成为纯粹而一致的对象模型;还介入了迭代器,受CLU和Icon启发的生成器,和描述器协议。Python 2.3介入了从Dylan引进的方法决定次序。Python 2.4介入了集合类型,和函数修饰器。Python 2.5介入了with语句,并在官方实现中介入了抽象语法树。
在2008年12月,Python 3.0發布,它对语言做了较大修订而不能完全后向兼容,尽管提供了进行自动转换的2to3实用工具,仍有大量现存代码不能移植,故而Python 2.7的产品寿命结束延期至2020年元旦。Python 3.4介入了异步I/O模块。Python 3.5介入了类型提示,和采用async/await语法的协程。Python 3.8介入了赋值表达式。
在2020年10月,Python 3.9介入了内建的针对容器类的泛化别名(types.GenericAlias)类型,并在官方实现中介入了新的语法解析器。Python 3.10介入了结构式模式匹配,和内建的联合类型(types.UnionType)。Python 3.11对官方实现进行了优化提速。Python 3.12介入了类型参数语法和type语句,并废弃或移除了一些过时的模块和功能。Python 3.13介入了从PyPy引进的新交互式解释器,并实验性的支持了在自由线程模态下运行和即时编译器。
每个版本首次发行后,享有2年的完全支持,随后是3年的安全支持。当前只有Python 3的稳定版本3.12与3.13正在被完全支持,但仍提供对3.9、3.10和3.11版本的安全性修正。
在2024年12月,活跃的Python核心开发者,选举Pablo Galindo Salgado、Barry Warsaw、Emily Morehouse、Gregory P. Smith和Donghee Na,为2025年度“掌控委员会”的五位成员来领导这个项目。
== 特徵與設計哲學 ==
Python是多范型编程语言。它完全支持结构化编程和面向对象编程,还有很多特征支持函数式编程和元编程比如元对象协议(元类和魔术方法)。通过扩展还可以支持很多范型,包括面向方面编程、契约式设计和逻辑编程。
Python使用动态类型,在内存管理上采用的垃圾回收器基于了引用计数,并且结合了检测环引用的分代垃圾回收优化。它的特征还有动态名字解析(后期绑定),即在程序执行期间绑定方法和变量的名字。
Python對遵循LISP傳統的函数式编程提供了有限的支持,它提供了 map、filter和reduce函数;列表推导式、字典推导式、集合推导式和生成器表达式。標準庫中的模組functools和itertools,实现了从Haskell和Standard ML借鉴来的函數式工具。
Python的設計理念是“優雅”、“明確”、“簡單”,它的一些重要準則被合稱為「Python之禅」。在Python解釋器内運行import this可以獲得完整的列表,下面举出其中首要:
優美优于丑陋。明瞭优于隐晦。
简单优于复杂。复杂优于凌乱。
扁平优于嵌套。稀疏优于稠密。
可读性很重要。
Python開發者的方法论是“用一種方法,最好是只有一種方法來做一件事”,显著不同于以Perl语言为代表的“不止一种方法去做一件事”風格。Python開發者在設計語言時,如果面臨多種選擇,一般會選擇明確没有或者很少有歧義的語法。
范羅蘇姆认为ABC語言非常優美和强大,它没有取得成功的原因是不開放造成的,故而将Python本身設計為可擴充的。Python並不把所有的特性和功能都集成到語言核心,而是提供了豐富的API和工具,以便程式設計師能够輕鬆地使用Python、C语言、Cython來編寫擴充模組。Python还可以通过外界函数接口如标准库中的ctypes等,来提供C语言兼容数据类型,并访问动态链接库或共享库中的函数,从而对用其他語言編寫的程式進行集成和封裝。
在Python的官方实现CPython中,一般避開不成熟的或者對非重要部位的加快運行速度的優化。在某些對運行速度要求很高的情況,可以使用具备JIT技术的Python实现或安装JIT扩展模块。
== 語法和语义 ==
Python為了讓程式碼具備高度的可閱讀性,在設計時盡量使用了其它語言常用的符號和英文單字。
=== 行结构 ===
Python程序在词法分析上被分成若干逻辑行。简单语句包含在一个单一的逻辑行之内,Python支持使用分号作为分隔符,将多个简单语句合并入一个逻辑行之中。
注释开始于并非字符串文字一部份的一个井号#,并结束于物理行结尾;注释标示逻辑行的结束,除非已受制于隐式行接续规则;注释在语法上被忽略。
Python支持使用反斜杠作为行接续符,将多个物理行合成为一个逻辑行。在圆括号、方括号或花括号之中的表达式,可以分裂跨越多于一个物理行而不使用反斜杠,这被称为“隐式行接续”。
=== 縮排 ===
Python语法中的复合语句,包含了一些其他语句,它们以某种方式影响或控制这些其他语句的执行。Python的复合语句包含一个或多个子句(clause),子句构成自一个头部(header)和一个套件(suite)。特定复合语句的子句头部都在同样的缩排层级上,每个子句头部开始于一个唯一标识关键字,并结束于一个冒号。套件即语法意义上的块,是这个子句所控制的一组语句。
套件有两种形式:可以是与头部在同一行上的一个或多个由分号分隔的简单语句,它们跟随在这个头部的冒号之后;或者是遵循越位規則的在连续诸行上的一个或多个縮排的语句,只有这种套件形式可以包含嵌套的复合语句。
根據PEP 8的規定,使用4個空格來表示每級縮排。
缩排层级的变迁,被用来生成语法解析器才能见到的INDENT和DEDENT记号,增加縮排就生成INDENT记号,減少縮排就生成DEDENT记号。二者的作用相当于C语言家族的花括号,或Pascal语言家族的关键字begin和end。
=== 关键字 ===
Python有如下35个关键字;它们不能用作标识符:
内建常量True、False和None于Python版本3.0中成为关键字,关键字nonlocal介入于版本3.0,关键字async和await介入于版本3.5,并在版本3.7中成为正式关键字。
在Python中,将只在特定上下文中保留的标识符,称为“软关键字”:
match、case和通配符_,介入于版本3.10,它们在与模式匹配语句有关的上下文中,可以在语法上充当关键字;但是这种区分只在语法解析器层次进行,并非在词法分析记号化层次。
type,介入于版本3.12,它用在type语句之中。
=== 标识符 ===
标识符就是名字,在ASCII范围内(U+0001..U+007F),可用于标识符的字符为:大写字母A至Z和小写字母a至z,下划线_以及数字0至9,但首字不可以用数字。如下命名约定,是为“保留标识符类”:
_spam(单下划线开头):弱“内部使用”标识。对于from M import *,将不导入所有以下划线开头的对象。
spam_(单下划线结尾):为了避免与python关键字的命名冲突。
__spam(双下划线开头):在命名一个类特性的时候,采用名字修饰,比如在类SpamEggs内,__spam将变成_SpamEggs__spam。
__spam__(双下划线开头双下划线结尾):指那些包含在用户控制的命名空间中的“魔术”方法或特性,比如__delattr__、__dir__、__doc__、__getattribute__、__init__、__new__、__repr__、__setattr__、__sizeof__等。建议永远不要将这样的命名方式应用于自己的变量或函数。
=== 語句 ===
Python的语句包括简单语句:
赋值语句,采用的中缀记号是等号=。赋值语句被用来将名字绑定(含重新绑定)到值,以及用来修改可变对象的特性或项目。
Python还支持增广赋值语句,将一个二元运算和一个赋值语句合并成一个单一语句,例如x += 1。
Python支持“序列解包”(sequence unpacking):在等号左侧可以是一个表达式列表,其中每个表示式都可求值成能被赋值的东西(变量、可写特性等);在等号右侧相应的是一个“可迭代”对象,它在被迭代时产生的值的数量,同于左手侧可写表达式的数量;赋值语句对这个对象进行迭代,将产生的每个值分别赋值给左侧对应的可赋值者。在等号右侧直接包装出序列解包所要求的元组,就形成了并行赋值,可以同时给多个变量赋值,还可以交换两个变量的值。
表达式语句,用来交互式的计算并写出一个值,或者用来调用一个过程(即返回无含义结果的函数),在Python中过程返回值None。
global语句,是在整个当前代码块中成立的声明,它意味着随后列出的标识符被解释为全局变量。
nonlocal语句,导致随后列出的标识符,提及在除了全局作用域之外的最近包围作用域中的先前绑定变量。
type语句,介入于版本3.12,声明作为类型别名类型(typing.TypeAliasType)的实例的一个类型别名。
pass語句,充当NOP,表示此行為空,不執行任何操作。
assert語句,用於程式調適階段時測試執行條件是否滿足。
continue语句,越过这次迭代并继续进行下个项目。
break语句,从循环中跳出。
return语句,用来从函数返回值。当函数执行到return语句时,它会停止执行并将指定的值返回给调用者。
raise语句,抛出一个例外。
yield语句,使用它从一个生成器中返回一个值。在版本2.5之前,信息只能单向的从生成器传递出来。
自此版本2.5,重定义yield为表达式,通过它的返回值将信息传递进入生成器函数中,从而能够支持协程功能。yield语句在语义上等价于加圆括号的yield表达式。
自从版本3.3,提供了yield from语句,含有这个语句的“委托生成器”将其部份运算委托给另一个“子生成器”,将传入信息递送给它并直接回传它产生的值。版本3.4在异步I/O框架中扩展了基于生成器的协程,这个扩展自从Python 3.8已经被弃用。
自从版本3.6,介入了生成async for语句所用的异步迭代器的异步生成器。
import语句,导入一个模块或包,它组合了两种操作,查找指名的模块,接着将找到的结果绑定到在局部作用域中的名字。导入语句有三种形式(下述语句样本中的方括号表示其中内容为可选的):
import 模块名字 [as 别名],找到一个模块,装载它,如果有需要的话初始化它;在这个导入语句出现的作用域的局部名字空间中,定义一个名字或一些名字。
from 模块名字 import 定义1 [as 别名1], 定义2 [as 别名2], ...,找到、装载、必需时初始化一个模块;接着在局部名字空间中,增加到找到指名特性的引用。
from 模块名字 import *,在导入语句出现的作用域的局部名字空间中,绑定模块中定义的所有公开的名字。
del语句,递归的进行删除。
复合语句:
if語句,當條件成立時執行語句套件。它經常包含elif、else子句。
while語句,當條件為真時,重複執行語句套件。
for語句,遍历列表、字符串、字典、集合等迭代器,依次處理迭代器中的每個元素。
match语句,用于模式匹配。
try語句,它经常包含except、else、finally子句,處理在程式執行中出现的異常情況。Python支持并广泛使用例外处理,作为检测错误状况和程序中其他“例外”事件的方式,并提倡在可能出现错误状况的任何时候都使用例外。习惯上访问一个文件或资源不在使用之前进行测试,而是先行尝试使用它,再捕获访问被拒绝引发的例外。Python 3.11介入了except*子句。
with語句,把一块代码包裹在一个上下文管理器之内。它允许了资源获取即初始化(RAII)式行为,可替代常见的try/finally惯用法。Python使用with语句处理资源,在进入一个作用域的时候调用一个函数,而在离开它的时候调用另一个函数,例如:在一块代码执行之前获取一个锁,并且在此后释放这个锁;或事先打开一个文件,并且事后关闭它。
class語句,是定义类的可执行语句。类的继承列表给出基础类列表,没有继承列表的类,缺省继承基础类object。类的套件接着在新的执行框架(frame)中执行,它使用新建的局部名字空间和原来的全局名字空间。当这个类套件完成执行之时,丢弃它的执行框架并保存它的局部名字空间。一个类对象接着被创建,其基础类采用继承列表,其特性字典采用保存的局部名字空间。类名字接着在原来的局部名字空间中,被绑定到这个类对象。
def語句,是定義函數和方法的可执行语句。它的执行在当前局部名字空间中,将函数名字绑定到一个函数对象(对函数的可执行代码的包装器)。这个函数对象包含到当前全局名字空间的引用,作为调用这个函数时使用的全局名字空间。
async def语句,用于协程函数定义。await表达式、async for语句和async with语句,只能用在协程函数的主体中。
=== 块与模块 ===
在Python的执行模型中,程序构造自块(也称为代码块)。块是作为一个单元执行的Python程序文本,模块、函数主体和类定义都是块。交互式键入的每个命令、脚本文件和脚本命令都是块。传递给内建函数eval()和exec()执行的字符串是块。块在执行框架(frame)中执行。框架包含一些用于调试的管理信息,并确定在这个块执行完成后,执行在何处以及如何继续。
模块是包含Python定义和语句的一个文件,这个文件名字是模块名字附加上后缀.py;在一个模块中,模块的名字(作为字符串)可获得为全局变量__name__的值。包(package)是可以包含子模块或递归性的子包的模块。包在技术上是具有__path__特性的Python模块。可以将包视为文件系统上的目录,而将模块视为这种目录中的文件,但是包和模块不必然源自文件系统。
名字即标识符,是通用的引用持有者,它不关联于一个固定的数据类型,但是,一个名字在给定时间,总是被绑定到有一个类型的某个对象上,这就是动态类型的特征。名字的存储位置不“包含”所指示的值,一个共同的值可以赋值给多个名字,一个名字在任何时候,都可以重新绑定到各种不同类型的对象上,包括字符串、过程、具有数据和方法的复杂对象等。
如果一个名字绑定在一个块中,它是这个块的局部变量,除非被声明为nonlocal或global。如果一个名字绑定在模块层次,它是全局变量。模块对应的块的变量,既是局部的也是全局的。如果一个变量使用在一个块中,却不定义在这里,它是自由变量。
在Python中,赋值所进行的操作,是将一个名字绑定为到一个分立的动态分配的对象的一个引用。
作用域定义一个名字在一个块中的可见性。如果一个局部变量被定义在一个块中,它的作用域包括这个块。如果这个定义出现在一个函数块中,作用域扩展到在所界定作用域内包含的任何块,除非所包含的块为这个名字介入了不同的绑定。对一个块可见的所有这种作用域的集合,叫做这个这个块的“环境”。
当一个名字在一个块之中使用,它采用最近包围作用域来解析。如果一个名字绑定在一个块中,并且在其中于绑定之前就被使用,会导致一个错误。当一个函数或类的定义被嵌套到其他函数的定义之内,它的非局部作用域就是这个包围函数的局部作用域。nonlocal语句导致其列出的标识符,提及在非局部作用域内先前绑定的名字(即非局部变量)。
名字空间是存储变量的地方,它被实现为字典。有局部名字空间、全局空间即包含这个块对应的模块的名字空间,和内建名字空间即模块builtins的名字空间;对象的方法是定义在类主体内的函数,它有着嵌套的名字空间。名字空间通过防止命名冲突而支持了模块性,还通过明晰了哪个模块实现了哪个函数而增进可读性和可维护性。
如果global语句出现在一个块之中,在这个语句中指定的所有名字,提及在顶层名字空间中这些名字的绑定。名字在顶层名字空间解析,首先查找全局名字空间,未果查找内建名字空间。global语句与在同一个块中的名字绑定运算有同样的作用域。如果一个自由变量的最近包围作用域包含针对它的global语句,这个自由变量被当作全局的。
=== 表达式 ===
Python中很多表达式与C语言和java类似,而另一些则与之不同。
在Python中,算术运算的加法+、减法-、乘法*和取模%是与C语言和java相同的,但是除法的行为不同。在Python中有两种除法,它们是下取整除法(或整数除法)//和浮点除法/。Python增加了指数算符**。自从Python 3.5,介入了矩阵乘法算符@,它已经用于了NumPy库。
在Python中,有如下必须用于整数的位运算:&与(AND),|或(OR),~非(NOT),^异或(XOR),>>右移, <<左移。
在Python中,有如下比较运算:大于>,小于<,等于==,不等于!=,小于等于<=,大于等于 >=。==按值比较。Python的is、is not算符可以用来比较对象的同一性(按引用比较),也就是比较两个变量是否引用了同一个对象。而in、not in用于判断一个对象是否属于另外一个对象。在Python中,比较是可以链接起来的,比如a < b < c。
Python使用and、or、not表示逻辑运算与、或、非,不采用C语言和Java中所用的符号&&、||、!。
在Python中,由逗号,分隔的一组表达式,叫做表达式列表。Python为构造列表、字典或集合,提供了叫做“展示”(display)的特殊语法,它们每个都有两种方式:包容内容要么显式列举出来;要么通过一组循环和过滤指令计算而来,这叫做“推导式”。列表展示是包围在方括号中的可以为空的一系列表达式,一个例子列表可写为[1,2,3]。字典展示是包围在花括号中的可能为空的一系列的键/数据项对。集合展示用花括号来指示,与字典展示的区别是缺少分隔键与值的分号。自从Python 3.5,增加了在表达式列表中的“可迭代解包”*,和在字典展示中的“字典解包”**。
Python支持列表推导式。Python 2.4将列表推导式扩展至更一般性的生成器表达式。Python 3.0又增补了字典推导式和集合推导式。
在Python中,加圆括号形式(parenthesized form),是包围在圆括号中的一个可选表达式列表。加圆括号的表达式列表产生的东西,就是这个表达式列表所产生的:如果这个列表包含至少一个逗号,它产生一个元组;否则它产生构成这个表达式列表的那个单一表达式。一个例子元组可写为(1,2,3)。元组不是圆括号形成的,而是使用逗号形成的,在没有歧义的情况下,元组的圆括号是可选的。空的圆括号对产生空元组对象。使用序列串接算符+来串接二个元组,产生包含给定元组二者的元素的一个新元组。
Python支持在序列对象(比如字符串、元组或列表)上的下标(subscription)表达式:a[索引],和分片表达式:a[开始:停止]或a[开始:停止:步长]。下标索引是基于零的,负数是相对于结尾的。分片范围自从“开始”索引,直到但不包括“停止”索引。分片的第三个参数叫做“步长”(step)或“间隔”(stride),允许元素被跳过和用负数指示反向。分片索引可以省略,例如a[:],这返回整个列表的一个复本。分片的每个元素都是浅层复制的。
Python的条件表达式表示为x if c else y。意思是当c为真时,表达式的值为x,否则表达式的值为y。 在运算元的次序上不同于很多其他语言中常见的c ? x : y。
Python的匿名函数实现为lambda表达式。匿名函数体只能是一个表达式。
自从Python 3.8,介入了赋值表达式,其记号是:=。它将一个表达式赋值给一个标识符,同时还返回这个表达式的值。赋值表达式在用作子表达式,即位于分片表达式、条件表达式、lambda表达式、关键字参数中的表达式和推导式中的if表达式之中,以及在assert和with语句之中的时候,必须围绕着圆括号。在它们可以使用的所有其他地方,包括在if和while语句之中,都不要求圆括号。
Python中运算符具有优先级,下表中的运算符按照从最高到最低的次序列出。在相同单元格中运算符具有相同的优先级,它们从左至右结合,除了指数表达式和条件表达式从右至左结合之外:
Python提供了序列串接算符+和序列倍增算符*。自从Python 3.9,介入了字典归并算符|和字典更新算符|=。
Python的文本序列类型,包括字符串str和字节序列bytes与bytearray。字符串文字有多种写法,字符串对象有一个内建格式算符%:
短字符串文字,由单引号'或双引号"界定。不同于Unix shell、Perl和受Perl影响的语言,单引号和双引号功能相同。这二种字符串都使用反斜杠\作为转义字符。
长字符串文字,是开始并结束于三个单引号'''或三个双引号"""的序列。它们可以跨越多行,其功能就像shell、Perl和Ruby中的here文档。
字节文字总是前缀上一个b或B,它产生bytes类型的实例。它们只可以包含ASCII字符,具有128或更大数值的字节必须通过转义来表达。
字符串文字或字节文字都可选的能前缀上一个r或R,这叫做原始字符串。转义序列不被解释,因此在文字反斜杠常见的地方很有用,比如正则表达式和Windows风格的路径。这种引述可比较于C#中的“@引述”。
Python允许多个毗邻的字符串文字或字节文字(它们以空白分界并可以使用不同的引述约定),在编译时间于语法层面上串接起来。要在运行时间串接字符串,必须使用序列串接算符+。
Python中的“字符串格式”算符%,在功能上类同于C语言中的printf格式化字符串,例如"spam=%s eggs=%04d" % ("blah", 2),求值为'spam=blah eggs=0002'。自从Python 3.0,str类提供了可供替代的format()方法,例如"spam={0} eggs={1:04d}".format("blah", 2)。在Python 3.6中,提供了“格式化字符串文字”或称为“f字符串”,它向字符串文字前缀上f或F,这是一种字符串插值,例如x="blah"; y=2; f'spam={x} eggs={y:04d}'。
在Python中,在表达式和语句之间的区别是严格强制性的,这对比于语言如Common Lisp、Scheme或Ruby。故而Python中个别构造存在功能重复,比如:列表推导式相当for循环;条件表达式相当if语句;内建函数eval()相当exec(),前者用于表达式,后者用于语句。
语句不能成为表达式的一部份,由于列表和其他推导式或lambda表达式,都是表达式,也就不能包含语句。这个限制的一个示例:赋值语句比如a = 1,不能用作条件语句的条件判断表达式的一部份;这能够避免C语言编程中的一个常见错误,即在条件判断时把等于算符==误写为赋值算符=,这不是预期代码却在语法上有效而能通过编译器检查,在Python中这会导致一个语法错误。
=== 函数 ===
Python的函数支持递归和闭包,及其他头等函数特征,但不支持函数重载。Python的函数作为头等对象,具有和普通对象平等的地位。Python官方实现不提供尾调用优化或头等续体,吉多·范罗苏姆曾声称永远都不会加以支持,但有第三方库支持弹跳床。
Python可以在函数定义时,于形式参数序列中,指定形式参数缺省值,即以param=value样式进行一次性初始化。形式参数在初始化之后,保持既有绑定;函数的后续调用,可继续对它进行访问或变更。为有缺省值的形式参数提供实际参数,在函数调用时是可选的。
Python的函数实际参数与形式参数之间的结合,是传递“对象引用”,函数在被调用的时候,给函数调用的实际参数,被介入到一个局部符号表中,实际参数使用传值调用来传递,而这个值总是对象引用,而非这个对象的值。如果形式参数绑定到一个可变的对象,则通过形式参数对此对象内容的修改,在函数外也是可见的。如果形式参数绑定到一个不可变的对象,则通过形式参数是不能修改此对象内容,但可以把形式参数重新绑定到其它对象上,这并不影响函数外的对象的值。
Python支持位置实际参数和关键字实际参数。函数调用时,实际参数可以如同C语言那样,按照位置与形式参数匹配;也可以采用命名参数或称为关键字实际参数,即kwarg=value样式的实际参数。使用不对应实际参数的特殊形式参数/和*,可以将参数序列分为三部份:唯位置参数、可位置可关键字参数和唯关键字参数。有缺省值的形式参数之后,不能跟随无缺省值的可位置形式参数。在一个函数调用的实际参数序列中,关键字实际参数必须出现在位置实际参数之后。
在位置和关键字形式参数序列末尾,可以分别有*args或**kwargs这样的形式参数,它们对应于在函数调用时提供的,超出形式参数序列规定而无所对应的多个实际参数;在形式参数名字前加一个*号,该形式参数args是tuple类型,对应可变数目的位置实际参数;在形式参数名字前加**号,该形式参数kwargs是dict类型,对应可变数目的关键字实际参数。如果位置实际参数已经在一个序列类型如列表或元组的对象中,在引用它的变量前加一个*号传递给函数,则其中所有元素解包为多个位置实际参数;如果关键字实际参数在字典中,则加**号来传递给函数。
修饰器(decorator)可用来修改一个函数、方法或类定义的任何可调用Python对象。将已定义的原来对象传递给修饰器,它返回一个修改后的对象,接着把它绑定到在定义中那个名字。Python修饰器部份受到Java注解的影响,而有类似的语法;修饰器语法是纯粹的语法糖,使用@作为关键字形成修饰符。修饰器是一种形式的元编程,它们增强它们所修饰的函数或方法的行动。
多个修饰器可以链接起来,通过在毗连的行上放置多个修饰符,或者使用中间变量。
函数修饰器的正规用法包括:用来建立类方法或静态方法、设置先决条件和后置条件、实现多方法、增加函数特性、跟踪、同步;此外更远大的用法包括:尾调用消除、记忆化。
为了增强代码的可读性,可以在函数后书写“文档字符串”(简称docstrings),用于解释函数的作用、参数的类型与意义、返回值类型与取值范围等。可以使用内置函数help(),打印出函数的使用帮助。自从Python 3.0,函数可以对参数与返回值增加类型标注。此特性可方便对源代码进行更深入的分析。自从Python 3.5,开始支持类型提示。
=== 对象及其方法 ===
Python支持大多数面向对象编程技术。在Python中所有东西都是对象,包括类、函数、数和模块。它允许多态性,不只是在类层级之内,而且通过采用鸭子类型的方式。任何对象可以用于任何类型,只要它有适当的方法和特性(attribute)就能工作。Python天然支持类的继承包括多重继承,为此采用C3线性化或方法决定次序(MRO)算法,还支持混入。Python支持元类,自从Python 3.6,提供了定制类创建的简单机制。
Python使用名字修饰,有限的支持私有变量。对象的(可写)特性可以被提取为一个字典。在Python中,不强制使用访问子与变异子方法,来访问数据成员的面向对象编程信条。就像Python提供函数式编程构造,但不尝试要求参照透明性一样,它提供对象系统,但不要求面向对象编程行为。
对象的方法,是附属于这个对象的类的函数。对于正常的方法和函数,语法instance.method(arguments),是Class.method(instance, arguments)的语法糖。Python的方法有显式的self形式参数,用来访问实例数据;这借鉴自Modula-3,对立于隐式的self或this关键字,它们用在其他一些面向对象编程语言,比如C++、Java、Objective-C或Ruby之中。在Python中,self可以被看作是一个习惯用法,它可以被换为任何其它合法的参数名。
Python提供了super()内建函数,在一个类的方法中调用此函数返回一个代理(proxy)对象,它将其方法调用委托给这个类的父类或兄弟类,当一个子类的方法覆盖了超类方法的时候,可通过调用super().method,来调用与子类的self.method方法同名超类方法。
Python支持一些以__开始和结束的特殊方法名,它们用于实现运算符重载,以及实现多种特殊功能。在Python中,可以通过定义特殊方法来重载运算符,比如在一个类上定义__add__(),将允许在这个类的实例上使用+算符。
在Python中,定义了一个或多个特殊方法__get__()、__set__()、__delete__()的类,可以用作描述器(descriptor)。建立一个描述器的实例,作为另一个类的一个类成员,使得这个实例成为此另一个类的属性(property)。使用与特性(attribute)访问相同的语法,访问一个实例对象中的这个成员属性。
Python允许通过使用@classmethod和@staticmethod修饰符,来分别建立类方法和静态方法。给类方法的第一个实际参数,是对类对象的引用,而非对实例的self引用。静态方法没有特定的第一个实际参数,实例或类对象,都不固定的传递给静态方法。
Python的property内建函数,将一个类中特殊定义的访问一个特性的那些方法,包装成的这个类的一个属性。
=== 类型 ===
Python使用鸭子类型,并拥有有类型的对象,和无类型的变量名字。在编译期不检查类型约束,而宁愿在一个对象上的操作出现可能的失败,表现出这个给定对象不具有适合的类型。尽管是动态类型系统,Python却是强类型的,禁止没有明确定义的操作(比如加一个数到一个字符串),而不是默默的去尝试转换使其有意义。Python支持广泛的类型和类的内省。类型是type的实例,可以被读取和比较。
Python有着范围广泛的基本数据类型。同时具备常规的整数和浮点算术,它透明的支持任意精度算术、复数和十进制浮点数。Python支持种类繁多的字符串操作。在Python中,字符串是不可变的,所以在其他编程语言中可能就地改变字符串的字符串操作,比如字符替换,在Python中返回新的字符串。
Python有一个非常有用特征,就是搜集(或称容器)类型的概念。一般的说,搜集是以一种易于引用或索引的方式,包含其他对象的对象。搜集有二种基本形式:序列和映射。Python对建立容器类型的对象有着语法上的支持。Python还提供了广泛的搜集操纵能力,比如内建的包含元素检查和通用迭代协议。
有次序的序列类型是列表(动态数组)、元组和字符串。所有序列类型都是位置索引的,并且除了字符串,都可以包含任意类型的对象,在同一个序列中包括多种类型的对象。字符串和元组是不可变的,使得它们成为字典的键的完美候选者。在另一方面,列表是可变的,元素可以被插入、删除、修改、添加或就地排序。
在另一方面,映射是以“字典”形式实现的无次序的类型,它将一组不可变的键,映射到相应的元素上(非常像数学函数)。在字典中的键,必须是不可变的Python类型,比如整数或字符串,因为在底层它们是通过散列函数实现的。字典还是语言内部的中心,因为它们居于所有Python对象和类的核心:在变量名字(字符串)和这个名字所引用的值之间的映射,就存储为字典,而这些字典可以通过对象的__dict__特性直接访问。
集合搜集类型,在版本2.4中被增加入语言核心。集合是无索引、无次序的搜集,它包含唯一性的不可变对象作为元素,并且实现了集合论运算,比如并集|、交集&、相对补集-、对称差^,和子集测试<=、真子集测试<、超集测试>=、真超集测试>。有二种类型的集合:可变的set和不可变的frozenset。
Python允许编程者使用类,定义自己的类型,类是在面向对象编程中最经常使用的。类的新实例,是通过调用这个类的构造器而创建的,而类都是元类type的实例,type是type元类自身的实例,这允许了元编程和反射。
在版本3.0之前,Python有两种类:旧式的和新式的。二种样式的语法是一样的,不同在于是否直接或间接的继承自类object,所有新式类都从object继承,并且是type的实例。在Python 2系列2.2以上,二种类都可以使用。在Python 3.0中淘汰了旧式类。
长期规划是支持渐进类型,并且自从Python 3.5,语言的语法允许指定静态类型,但在缺省实现CPython中不检查它们。有叫做“mypy”的可选的静态类型检查器,支持编译期类型检查。
除了各种数据类型,Python解释器还内建了很多其他类型,包括可调用类型:用户定义函数、实例方法、生成器函数、协程函数、异步生成器函数、内建函数、内建方法、类、类方法;模块,定制类,类实例,I/O对象(也叫做文件对象),和暴露给用户的一些内部类型:代码对象、框架对象、溯回对象、切片对象、静态方法对象、类方法对象。
=== 算术运算 ===
Python的算术运算,使用平常的符号+、-、*、/和模除%。它还有下取整除法算符//、指数算符**和矩阵乘法算符@。二元运算先将两运算元转为共同类型,加法、减法、乘法、下取整除法和指数运算的结果也采用此类型,比如5**3 == 125而9**0.5 == 3.0。这些算符就像在传统数学中一样运算,具有同样的优先级规则,中缀算符+、-,还可以分别表示取原数和取相反数的一元算符。
被称为“真除法”的/的表现,随着版本不同而有着显著变化。自Python 3.0以来,/总是产生浮点数结果,包括两个整数相除,比如5/2 == 2.5;而在下取整除法//中,两个整数相除产生整数,比如7//3 == 2而7.5//3 == 2.0。
下取整除法//的修约是朝向负无穷的。向下取整能增加一致性,例如这意味着等式(a + n)//n == a//n + 1总是为真。模除%所得出的余数的符号同于除数,比如-4%3 == 2而4%-3 == -2。其它多数编程语言比如C99采用截尾取整规则,余数的符号同于被除数。模除运算结果余数的定义,确使等式a == (a//n)*n + a%n对于a和n分别为正数或负数的情况都是有效的。余数可以为负数,显著不同于在数学中的欧几里得除法规则下,余数总是非负数的情况。
Python提供了round()内建函数,用于把一个浮点数修约成最近的整数,自Python 3.0以来,为了打破平局它采用了IEEE 754的约半成偶规则:round(1.5)和round(2.5)都产生2。
Python允许由比较运算链接起来的布尔表达式,表现得如在数学中常用的一样。比如表达式a < b < c,测试a < b and b < c。C语言将它解析为(a < b) < c:即首先求值a < b,其结果为0或1,接着把这个结果比较于c。
Python对所有整数运算,使用任意精度算术。在decimal模块中的Decimal类,提供十进制浮点数,具有用户可按需要而更改的缺省28个十进制有效数位精度,并有多种修约方式。在fractions模块中的Fraction类,提供任意精度的有理数。第三方库gmpy2,提供了到任意精度计算库GMP/MPIR、MPFR和MPC的接口。
除了求绝对值函数abs()列入内建函数之外,大多数数学函数,处于math和cmath模块内。前者用于实数运算,而后者用于复数运算。由于Python有着广泛的数学库,特别是第三方库NumPy进一步扩展了固有能力,Python经常被用作科学脚本语言,来处理如数值数据处理和操纵等问题。
== 标准库 ==
Python拥有一个强大的标准库。Python标准库包括了如下功能:
== 程序代码实例 ==
一個在標準輸出設備上輸出Hello World的簡單程式,這種程式通常作為開始學習程式語言時的第一個程式,可将如下代码录入纯文本文件并随意命名比如program01.py,然后执行这个程序python3 program01.py:
Python也可以單步直譯執行。執行Python直譯器進入互動式命令列的環境,你可以在提示符號>>>旁輸入print("Hello, world!"),按Enter鍵輸出結果:
计算正数的阶乘的程序代码:
注意,在Python 3.0及以上版本中,print是个函数,需要在要打印的字符串前后加上圆括号;在Python 2.6以下版本中,print是一个关键字和命令而不加圆括号。
== 实现 ==
Python是一门跨平台的脚本语言,Python规定了一个Python语法规则,根据该规则可编写Python直譯器。Python属于动态语言,其官方实现CPython将Python程序编译成中间形式的字节码,并接着在它的虚拟机上执行,运行速度缓慢于C/C++所编译出的机器码和在HotSpot JVM上运行的java字节码。
活跃开发的实现
转译成其他语言的编译器
其他实现举例:Jython,它是用Java实现的Python 2.7。IronPython,它是建造在DLR之上的Python 2.7和Python 3.4实现。Stackless Python,它是实现微线程的CPython 3.8分叉。Pyston,它是具有JIT等性能优化的CPython 3.8.12的分叉。Pyjion,将Python代码编译成本机CIL的CPython 3.10的JIT扩展。Cinder,它是Meta孵化器发布的具有包括JIT等很多优化的CPython 3.10分叉。Grumpy,它是Python 2.7到Go的转译器和运行时系统。py2many,起步于转译至Julia的PyJL的将Python转译成多种语言的转译器。
== 开发环境 ==
=== 通用文本编辑器 ===
很多并非集成开发环境软件的文本编辑器,也对Python有不同程度的支持,并且加上专门为Python设计的编辑器插件也会有很高的可用性。
=== 专用开发环境 ===
适用于Python的集成开发环境(IDE)软件,除了标准二进制发布包所附的IDLE之外,还有许多其他选择。其中有些软件设计有语法着色、语法检查、运行调试、自动补全、智能感知等便利功能。由于Python的跨平台出身,这些软件往往也具备各种操作系统的版本或一定的移植性。
== 第三方扩展包 ==
Python社群提供了大量的功能覆盖众多领域的第三方模組,其使用方式与标准库类似。第三方模块可以使用Python/Cython或者C语言编写。软件工具SWIG和SIP,通过定义接口文件或规定文件的方式,可以将C/C++编写的程序库包装为Python模块。Python解释器本身也可以被集成到其它需要腳本語言的程式内。
Python包索引是公开的软件包在线仓库。pip是官网推荐的以安全方式安装Python应用及其依赖软件包的最流行工具。要安装在整个操作系统范围内共享的Python包,现在需要通过操作系统的软件包管理系统。要将特定于应用的依赖包隔离于共享的Python安装,可以使用标准库的venv或第三方工具virtualenv创建虚拟环境;第三方工具pipenv,能自动为用户项目建立和管理虚拟环境,并在安装/卸装软件包的时候,向此项目的Pipfile文件增加/移除这个软件包。
=== 網絡编程 ===
Python對於各种網路協定的支援很完善,因此適用於編寫伺服器軟體、網路爬蟲等Web開發。Python定義了WSGI標準應用接口,来協調HTTP伺服器與基於Python的Web程式之間的溝通。比如,通過mod_wsgi模組,Apache HTTP Server可以運行用Python編寫的Web程式。
用Python编写的一些Web框架,有助於輕鬆地開發和管理複雜的Web程式。著名的第三方Web框架和函数库:
=== 图形用户界面 ===
Python本身包含了Tkinter库,它是Python的业界标准GUI并被集成进入了IDLE。Tkinter基于了Tcl命令工具,能够支持简单的GUI开发。但是为了让所开发的软件运行速度更快,并与用户的桌面环境更契合,人们一般会选择采用第三方GUI库或框架。著名的第三方GUI库:
=== 数据科学 ===
重要的数据科学用第三方软件库有:
==== 数据可视化 ====
主要的数据可视化软件库及仪表板框架有:
==== 机器学习 ====
基础性的机器学习软件库及框架有:
=== 其它种类 ===
== 应用 ==
在很多作業系統裡,Python是標準的系统元件,它被列入了ISO/IEC 23360-1-4:2021 Linux标准规范(LSB)之语言规定。大多數Linux發行版和macOS都集成了Python,可以在终端模拟器或虚拟控制台下直接執行Python。第三方工具pipx,可以将Python应用安装于隔离的环境中并在其中运行它。
雖然Python可被粗略地分類為腳本語言,Python的支持者較喜歡稱它為一種高階動態語言,常像“胶水”一样被用来连接软件组件,已经显著的区别于Unix shell、Windows PowerShell这样的语言。基于Python的xonsh,是跨平台的、青睐Unix的shell语言和命令行界面。
=== 应用程序 ===
一些Linux發行版,使用Python語言編寫安裝器,比如Ubuntu的Ubiquity和Fedora的Anaconda;或使用它編寫軟件包管理系统,比如Gentoo的Portage。如下著名应用使用Python编写或将它作为嵌入式脚本:
=== 人工智能 ===
经由Python开发了众多的人工智能模型和作为其支撑的软件库:
=== 社群流行 ===
自从2003年,Python始终排行于TIOBE编程社区索引前十最流行编程语言,在2021年10月它首次达到了第一名最流行语言(居于C和Java之前),并被选为2007年、2010年、2018年、2020年、2021年和2024年的年度编程语言。它有如下著名的社群:
== 影響的语言 ==
Python的设计和哲学已经影响了很多其他编程语言:
在Python基础上开发的编程语言有:
== 示例与注释 ==
== 引用 ==
== 延伸閱讀 ==
== 参閲 ==
== 外部連接 ==