Python为了让代码具备高度的可阅读性,在设计时尽量使用了其它语言常用的符号和英文单字。Python支持使用反斜杠作为行接续符,将多个物理行合成为一个逻辑行。在圆括号、方括号或花括号之中的表达式,可以分裂跨越多于一个物理行而不使用反斜杠,这被称为“隐式行接续”。注释开始于并非字符串文字一部分的一个井号#,并结束于物理行结尾;注释标示逻辑行的结束,除非已受制于隐式行接续规则;注释在语法上被忽略。简单语句包含在一个单一的逻辑行之内,Python支持使用分号作为分隔符,将多个简单语句合并入语法意义上的一行之中
。
Python语法中的复合语句,包含(成组的)其他语句;它们以某种方式影响或控制这些其他语句的执行。Python的复合语句包含一个或多个子句(clause),子句构成自一个头部(header)和一个包(suite)。特定复合语句的子句头部都在同样的缩排层级上,每个子句头部开始于一个唯一标识关键字,并结束于一个冒号。包是这个子句所控制的一组语句,包有两种形式,可以是与头部在同一行上的一个或多个由分号分隔的简单语句,它们跟随在这个头部的冒号之后;或者是在后续诸行上的一个或多个缩排的语句,只有这种包形式可以包含嵌套的复合语句
。
Python语言遵循越位规则,利用缩进来形成语句包,即语法意义上的块。连续诸行的缩排层级,被用来生成语法解析器才能见到的INDENT和DEDENT记号
,二者的作用相当于C语言家族的花括号,或Pascal语言家族的关键字begin和end。增加缩进就生成INDENT记号,减少缩进就生成DEDENT记号。根据PEP 8的规定,使用4个空格来表示每级缩进。tab字符(从左至右)被替代为1至8个空格,使得直到tab之前的诸字符加上这些替代空格的字符总数,是8的倍数(这意图同于Unix所用规则)。前导于第一个非空白字符的空格的总数,确定了这一行的缩排层级。缩排所用诸字符,不能使用反斜杠来拆分成多个物理行;直到第一个反斜杠之前的空白确定缩排层级。如果源代码文件混合了tab和空格,并且在这种方式下缩排的意义依赖于一个tab相当于多少个空格,则这种缩排因不一致性而被报错并拒绝
。
Python有如下35个关键字;它们不能用作标识符
:
内建常量True、False和None于Python 3.0中成为关键字,关键字nonlocal介入于Python 3.0
,关键字async和await介入于Python 3.5,并在Python 3.7中成为正式关键字
。
标识符match、case和通配符_介入于Python 3.10,它们在与模式匹配语句有关的上下文中,可以在语法上充当关键字;但是这种区分只在语法解析器层次进行,并非在词法分析记号化层次。在Python中,只在特定上下文中保留的这种标识符,叫做“软关键字”
。
标识符就是名字,在ASCII范围内(U+0001..U+007F),可用于标识符的字符为:大写字母A至Z和小写字母a至z,下划线_以及数字0至9,但首字不可以用数字。如下命名约定
,是为“保留标识符类”
:
在Python文献中经常使用的元语法变量是spam和eggs而非传统的foo和bar
。
Python的语句包括简单语句:
,将一个二元运算和一个赋值语句合并成一个单一语句,例如x += 1。Python支持“序列解包”(sequence unpacking):在等号左侧可以是一个表达式列表,其中每个表示式都可求值成能被赋值的东西(变量、可写特性等);在等号右侧相应的是一个“可迭代”对象,它在被迭代时产生的值的数量,同于左手侧可写表达式的数量;赋值语句对这个对象进行迭代,将产生的每个值分别赋值给左侧对应的可赋值者。在等号右侧直接包装出序列解包所要求的元组,就形成了并行赋值,可以同时给多个变量赋值,还可以交换两个变量的值。
自此版本2.5,重定义yield为表达式,通过它的返回值将信息传递进入生成器函数中,从而能够支持协程功能。自从版本3.3,提供了yield from语句,含有这个语句的“委托生成器”将其部分运算委托给另一个“子生成器”,将传入信息递送给它并直接回传它产生的值。yield语句在语义上等价于加圆括号的yield表达式。版本3.4在异步I/O框架中扩展了基于生成器的协程,这个扩展自从Python 3.8已经被弃用。版本3.6介入了异步生成器
。from 模块名字 import 定义1 [as 别名1], 定义2 [as 别名2], ...,找到、装载、必需时初始化一个模块;接着在局部命名空间中,增加到找到指名特性的引用。(这二个语句示例中的方括号表示其中内容为可选的。)from 模块名字 import *,在导入语句出现的作用域的局部命名空间中,绑定模块中定义的所有公开的名字
复合语句:
with语句,把一块代码包裹在一个上下文管理器之内。它允许了资源获取即初始化(RAII)式行为,可替代常见的try/finally惯用法。Python使用with语句处理资源,在进入一个作用域的时候调用一个函数,而在离开它的时候调用另一个函数,例如:在一块代码执行之前获取一个锁,并且在此后释放这个锁;或事先打开一个文件,并且事后关闭它。
模块是包含Python定义和语句的一个文件,这个文件名字是模块名字附加上后缀.py;在一个模块中,模块的名字(作为字符串)可获得为全局变量__name__的值。内建globals()函数,返回实现当前模块命名空间的字典。内建dir()函数,在无参数时,返回在当前局部作用域内的名字列表;在有一个参数时,尝试返回这个对象的有效特性的列表。包(package)是可以包含子模块或递归的子包的模块。包在技术上是具有__path__特性的Python模块。可以将包视为文件系统上的目录,而将模块视为这种目录中的文件,但是包和模块不必然源自文件系统
。
Python程序构造自代码块。代码块是作为一个单元执行的Python程序文本。模块、函数主体和类定义都是块。交互式键入的每个命令都是块。脚本文件和脚本命令是代码块。__main__是顶层代码运行所在的环境。“顶层代码”是启动运行的首个用户指定Python模块。从命令行使用-m参数,作为顶层脚本运行的模块(作为模块__main__)也是代码块。此时__name__变量被设置为"__main__",在这个模块中可籍此增加直接运行时候执行的代码
。传递给内建函数eval()和exec()执行的字符串是代码块。
在Python中赋值所进行的操作,是将一个名字绑定为到一个分立的动态分配的对象的一个引用。名字是通用的引用持有者,它不关联于一个固定的数据类型,但是,一个名字在给定时间,总是被绑定到有一个类型的某个对象上,这就是动态类型的特征。名字的存储位置不“包含”所指示的值,一个共同的值可以赋值给多个名字,一个名字在任何时候,都可以重新绑定到各种不同类型的对象上,包括字符串、过程、具有数据和方法的复杂对象等。
除了在块中出现的每个赋值语句或导入语句之外,下列构造也绑定名字:给函数的形式参数、类定义、函数定义、赋值表达式、在for语句头部中和各种as关键字之后的标识符目标(target),as关键字出现在import语句、with语句、except子句、except*子句和结构式模式匹配的as模式之中。如果一个名字绑定在一个块中,它是这个块的局部变量,除非被声明为nonlocal或global。如果一个名字绑定在模块层次,它是全局变量;模块代码块的变量,既是局部的也是全局的。如果一个变量使用在一个代码块中,却不定义在这里,它是自由变量
。
作用域定义一个名字在一个块中的可见性。如果一个局部变量被定义在一个块中,它的作用域包括这个块。如果这个定义出现在一个函数块中,作用域扩展到在所界定作用域内包含的任何块,除非所包含的块为这个名字介入了不同的绑定。当一个名字在一个代码块之中使用,它采用最近包围作用域来解析。对一个代码块可见的所有这种作用域的集合,叫做这个这个块的“环境”
。如果一个名字绑定在一个块中,并且在其中于绑定之前就被使用,会导致一个错误。如果global语句出现在一个块之中,在这个语句中指定的所有名字,提及在顶层命名空间中这些名字的绑定。名字在顶层命名空间解析,首先查找全局命名空间,即包含这个代码块的模块的命名空间;未果查找内建命名空间,即模块builtins的命名空间。global语句与在同一个块中的名字绑定运算有同样的作用域。如果一个自由变量的最近包围作用域包含它的一个global语句,这个自由变量被当作全局的。 nonlocal语句导致相应的名字,提及在最近包围函数作用域内的先前绑定变量(即非局部变量)。
Python中很多表达式与C语言和java类似,而另一些则与之不同。
,它已经用于了NumPy库
。自从Python 3.5,增加了在表达式列表中的“可迭代解包”*,和在字典显示中的“字典解包”**。
Python 2.4将列表推导式扩展至更一般性的生成器表达式。Python 3.0又增补了字典推导式和集合推导式。
。它将一个表达式赋值给一个标识符,同时还返回这个表达式的值。赋值表达式在用作子表达式,即位于分片表达式、条件表达式、lambda表达式、关键字参数中的表达式和推导式中的if表达式之中,以及在assert和with语句之中的时候,必须围绕着圆括号。在它们可以使用的所有其他地方,包括在if和while语句之中,都不要求圆括号
Python中运算符具有优先级,下表中的运算符按照从最高到最低的次序列出。在相同单元格中运算符具有相同的优先级,它们从左至右结合,除了指数表达式和条件表达式从右至左结合之外
:
运算符描述
(表达式...),[表达式...],{键: 值...},{表达式...}加圆括号表达式,列表显示,字典显示,集合显示
x[索引],x[索引:索引],x(参数...),x.特性下标,分片,调用,特性引用
await xawait表达式
**指数
+x,-x,~x取原数,相反数,逐位NOT
*,@,/,//,%乘法,矩阵乘法,除法,下取整除法,余数
+,-加法和减法
<<,>>移位
&逐位AND
^逐位XOR
|逐位OR
in,not in,is,is not,<,<=,>,>=,!=,==包含成员关系测试,同一测试,各种比较
not x布尔NOT
and布尔AND
or布尔OR
if – else条件表达式
lambdalambda表达式
:=赋值表达式
Python提供了序列串接算符+和序列倍增算符*
。自从Python 3.9,介入了字典归并算符|和字典更新算符|=
。
Python的文本序列类型,包括字符串str和字节序列bytes与bytearray。字符串文字有多种写法,字符串对象有一个内建格式算符%:
。
,例如"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()内建函数,当一个子类的方法覆盖了超类方法的时候,可通过调用super().method,来调用与子类的self.method方法同名超类方法。 Python支持一些以__开始和结束的特殊方法名,它们用于实现运算符重载,以及实现多种特殊功能
。在Python中,可以通过定义特殊方法来重载运算符,比如在一个类上定义__add__(),将允许在这个类的实例上使用+算符。
在Python中,定义了一个或多个特殊方法__get__()、__set__()、__delete__()的类,可以用作描述器(descriptor)
。建立一个描述器的实例,作为另一个类的一个类成员,使得这个实例成为此另一个类的属性(property)。使用与特性(attribute)访问相同的语法,访问一个实例对象中的这个成员属性。Python允许通过使用@classmethod和@staticmethod修饰符,来分别建立类方法和静态方法。给类方法的第一个实际参数,是对类对象的引用,而非对实例的self引用。静态方法没有特定的第一个实际参数,实例或类对象,都不固定的传递给静态方法。 Python的property内建函数,将一个类中特殊定义的访问一个特性的那些方法,包装成的这个类的一个属性。
Python 3的标准类型层级
Python使用鸭子类型,并拥有有类型的对象,和无类型的变量名字。在编译期不检查类型约束,而宁愿在一个对象上的操作出现可能的失败,表现出这个给定对象不具有适合的类型。尽管是动态类型系统,Python却是强类型的,禁止没有明确定义的操作(比如加一个数到一个字符串),而不是默默的去尝试转换使其有意义。Python支持广泛的类型和类的内省。类型是type的实例,可以被读取和比较。
Python有着范围广泛的基本数据类型。同时具备常规的整数和浮点算术,它透明的支持任意精度算术、复数和十进制浮点数。Python支持种类繁多的字符串操作。在Python中,字符串是不可变的,所以在其他编程语言中可能就地改变字符串的字符串操作,比如字符替换,在Python中返回新的字符串。
Python有一个非常有用特征,就是搜集(或称容器)类型的概念。一般的说,搜集是以一种易于引用或索引的方式,包含其他对象的对象。搜集有二种基本形式:序列和映射。Python对建立容器类型的对象有着语法上的支持。
Python还提供了广泛的搜集操纵能力,比如内建的包含元素检查和通用迭代协议。
有次序的序列类型是列表(动态数组)、元组和字符串。所有序列类型都是位置索引的(从0到长度−1),并且除了字符串,都可以包含任意类型的对象,在同一个序列中包括多种类型的对象。字符串和元组是不可变的,使得它们成为字典的键的完美候选者。在另一方面,列表是可变的,元素可以被插入、删除、修改、添加或就地排序。
在另一方面,映射是以“字典”形式实现的无次序的类型,它将一组不可变的键,映射到相应的元素上(非常像数学函数)。在字典中的键,必须是不可变的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 3内建类型小结 | |||
类型 | 可变性 | 描述 | 语法例子 |
bool | 不可变 | 布尔值,有表示值False和True的两个对象。作为整数类型numbers.Integral的子类型,它们在几乎所有上下文中,表现得如同0和1,除了在转换成字符串时转换为"False"和"True"之外。 | True |
int | 不可变 | 整数,其大小在理论上无限制,实际上受限于内存 |
。 | 42 | |
float | 不可变 | 双精度浮点数,确切精度依赖于机器。一般实现为IEEE 754标准binary64浮点数,它有53个二进制有效数位精度 |
。 | 1.414 | ||
complex | 不可变 | 复数,即分别表示实部与虚部的两个双精度浮点数的有序对。 | 3+2.7j |
range | 不可变 | 数的序列,通常用在for循环中指定循环次数 |
。 | range(1, 10) | ||
str | 不可变 | 字符串,即Unicode代码点序列。字符串中的代码点都在范围U+0000..U+10FFFF之内。Python没有char类型,这些代码点都表示为长度为1的字符串对象。 |
|
bytes | 不可变 | 字节序列,其项目是8位字节,用范围0 <= x < 256的整数表示。 | b'Some ASCII' |
bytearray | 可变 | bytearray(b'Some ASCII') | |
list | 可变 | 列表,可以包含任意的Python对象。 | [4.0, 'string', True] |
tuple | 不可变 | 元组,可以包含任意的Python对象。只有一个项目的元组,可以通过向表达式后缀一个逗号来形成。 | (4.0, 'string', True) |
dict | 可变 | 键-值对的关联数组(常称为字典),即由任意索引集合来索引的对象的有限集合。不可接受为键的值,是列表或字典,或按值而非对象同一性比较的其他可变类型的值,其散列值不能保持恒定。 | {'key1': 1.0, 3: False} |
set | 可变 | 无序有限集合,包含唯一性的不可变的对象,它们不能用任何下标来索引。 | {4.0, 'string', True} |
frozenset | 不可变 | frozenset([4.0, 'string', True]) | |
types.EllipsisType | 不可变 | 这个类型有一个单一对象作为值,它通过文字...或内建名字Ellipsis来访问,它的真值为真。它用于NumPy多维阵列索引 |
。 | ... | |
types.NoneType | 不可变 | 这个类型有叫做None的一个单一对象Null作为值 |
,它被用来指示值的缺席,比如不返回任何东西的函数返回它,它的真值为假。 | None | ||
types.NotImplementedType | 不可变 | 这个类型有一个单一对象NotImplemented作为值。数值方法和细化比较方法,在它们仍未对提供的运算数实现这个运算之时,返回这个值。它不应该在布尔值上下文中求值。 | NotImplemented |
除了各种数据类型,Python解释器还内建了很多其他类型,包括可调用类型:用户定义函数、实例方法、生成器函数、协程函数、异步生成器函数、内建函数、内建方法、类、类方法;模块,定制类,类实例,I/O对象(也叫做文件对象),和暴露给用户的一些内部类型:代码对象、框架对象、溯回对象、切片对象、静态方法对象、类方法对象。
Python的算术运算,使用平常的符号+、-、*、/和模除%(这里的余数可以是负数,比如4 % -3 == -2)。它还有下取整除法算符//,指数算符**,比如5**3 == 125及9**0.5 == 3.0,和矩阵乘法算符@
。这些算符就像在传统数学中一样运算,具有同样的优先级规则,中缀算符+、-,还可以分别表示取原数和取相反数的一元算符。
在整数之间的除法/,产生浮点数结果。除法/的表现,随着版本不同而有着显著变化
。 Python提供了round()内建函数,用于把一个浮点数修约成最近的整数
。
Python允许由比较运算链接起来的布尔表达式,表现得如在数学中常用的一样。比如表达式a < b < c,测试a < b and b < c
。C语言将它解析为(a < b) < c:即首先求值a < b,其结果为0或1,接着把这个结果比较于c
。
Python对所有整数运算,使用任意精度算术。在decimal模块中的Decimal类
,提供十进制浮点数,具有用户可按需要而更改的缺省28个十进制有效数位精度,并有多种修约方式。在fractions模块中的Fraction类,提供任意精度的有理数
。
由于Python有着广泛的数学库,除了求绝对值函数abs()列入内建函数之外,大多数数学函数,处于math和cmath模块内。前者用于实数运算,而后者用于复数运算。
特别是第三方库NumPy,进一步扩展了固有能力,Python经常被用作科学脚本语言,来处理如数值数据处理和操纵等问题
。
Python拥有一个强大的标准库
。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 = 1for i in range(2, n + 1): fact *= iprint(fact)
注意,在Python 3.0及以上版本中,print是个函数,需要在要打印的字符串前后加上圆括号;在Python 2.6以下版本中,print是一个关键字和命令而不加圆括号。
Python是一门跨平台的脚本语言,Python规定了一个Python语法规则,根据该规则可编写Python解释器
。Python属于动态语言,将Python程序编译成中间形式的字节码,并接着在它的虚拟机上执行,相较于C/C++和java的等编译语言而言运行速度较慢
。
活跃开发的实现
。其JIT部分,单独发行为扩展模块pyston_lite_autoload,它支持Python3.7—3.10
,它由MIT CSAIL的研究人员开发
到其他语言的交叉编译器
仍在维护中的旧版本实现有:Stackless Python,它是实现微线程的CPython 3.8分叉;IronPython,它是面向.NET和Ecma CLI的Python 2.7和Python 3.4实现;Jython,它是用Java实现的Python 2.7。
很多并非集成开发环境软件的文本编辑器,也对Python有不同程度的支持,并且加上专门为Python设计的编辑器插件也会有很高的可用性。
适用于Python的集成开发环境(IDE)软件,除了标准二进制发布包所附的IDLE之外,还有许多其他选择。其中有些软件设计有语法着色、语法检查、运行调试、自动补全、智能感知等便利功能。由于Python的跨平台出身,这些软件往往也具备各种操作系统的版本或一定的移植性。
Python Powered
主条目:Python软件列表
在很多操作系统里,Python是标准的系统组件,它被列入Linux标准规范之中
。大多数Linux发行版和macOS都集成了Python,可以在终端下直接执行Python。虽然Python可被粗略地分类为脚本语言,Python的支持者较喜欢称它为一种高阶动态语言,常像“胶水”一样被用来连接软件组件,已经显著的区别于Unix shell、Windows PowerShell这样的语言。基于Python的xonsh,是跨平台的、青睐Unix的shell语言和命令行界面
。
Python社群提供了大量的功能覆盖众多领域的第三方模块,其使用方式与标准库类似。第三方模块可以使用Python/Cython或者C语言编写。软件工具SWIG和SIP,通过定义接口文件或规定文件的方式,可以将C/C++编写的程序库包装为Python模块。Python解释器本身也可以被集成到其它需要脚本语言的编程内。
Python包索引是公开的软件包在线仓库。pip是官网推荐的以安全方式安装Python应用及其依赖软件包的最流行工具
。要安装在整个操作系统范围内共享的Python包,现在需要通过操作系统的软件包管理系统。要将特定于应用的依赖包隔离于共享的Python安装可以使用venv或virtualenv。pipx可以将Python应用安装于隔离的环境中并在其中运行它。pipenv能自动为用户项目建立和管理虚拟环境,并在安装/卸装软件包的时候,向此项目的Pipfile文件增加/移除这个软件包
。
自从2003年,Python始终排行于TIOBE编程社区索引前十最流行编程语言,在2021年10月它首次达到了第一名最流行语言(居于C和Java之前)
,并被选为2007年、2010年、2018年、2020年和2021年的年度编程语言
。
参见:Web服务
Python定义了WSGI标准应用接口,来协调Http服务器与基于Python的Web编程之间的沟通。比如,通过mod_wsgi模块,Apache可以运行用Python编写的Web编程。Zope是著名的用Python编写的开源的Web应用服务器。Tornado是用Python语言写成的非阻塞式web服务器,也是轻量级的Web框架。
Python对于各种网络协议的支持很完善,因此适用于编写服务器软件、网络爬虫等Web开发。用Python编写的一些Web框架,有助于轻松地开发和管理复杂的Web编程。著名的第三方Web框架和函数库:
参见:GUI
Python本身包含了Tkinter库,它是Python的业界标准GUI并被集成进入了IDLE。Tkinter基于了Tcl命令工具,能够支持简单的GUI开发。但是为了让所开发的软件运行速度更快,并与用户的桌面环境更契合,人们一般会选择采用第三方GUI库或框架。著名的第三方GUI库:
的GUI框架变换成简单的接口
重要的数据科学用第三方软件库有:
之上的框架,它将现代用户界面元素如下拉选单、滑动条和图形,直接链接至分析型Python代码。它和Streamlit、Panel和Voilà,是被称为“仪表板”的数据可视化工具
重要的人工智能机器学习框架有:
和threadpoolctl
,其中实现了Keras API。Keras现在是在TensorFlow 2上建立的深度学习高层API。SciKeras是对Keras模块的scikit-learn兼容的包装器
,结合了修改版本的针对NumPy的自动梯度库Autograd,和TensorFlow中的加速线性代数库XLA,它使用XLA来在GPU和TPU上编译和运行NumPy程序。JAX除了用于开发新的人工神经网络软件库比如Flax,还用于概率编程库比如NumPyro,和物理引擎比如Brax
。它构成自一个核心的分布式运行时系统,和加速机器学习工作负载的软件库工具箱(Ray AIR)。它支持TensorFlow或PyTorch,可集成于Dask、Apache Spark和Mars
,PyCUDA提供对CUDA并行计算API的Python风格访问;PyOpenCL提供对OpenCL并行计算API的Python风格访问
。创建PDF文件可以采用reportlab
一些Linux发行版,使用Python语言编写安装器,比如Ubuntu的Ubiquity和Fedora的Anaconda;或使用它编写软件包管理系统,比如Gentoo的Portage。一些著名的互联网公司在内部使用Python
。一些游戏比如EVE,使用Python编写游戏的逻辑、服务器。如下著名应用使用Python编写或将它作为嵌入式脚本:
Python的设计和哲学已经影响了很多其他编程语言:
Ruby的创建者松本行弘曾说过:“我想要一种脚本语言,比Perl更加强力而且比Python更加面向对象,因此我决定设计自己的语言”
。Julia设计原则中有一条是:“像Python一样可用于通用编程”
。
产生素数的惰性生成器的示例:
from itertools import countdef 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 isliceprimes_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))
列表的推导式示例。比如:
>>> [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]))
字典推导式{expr1: expr2 for k, v in d},等价于:
result={}for k, v in d.items(): result[expr1]=expr2return result
>>> {x: x + 3 for x in range(4)}{0: 3, 1: 4, 2: 5, 3: 6}
result = set()for x in stuff: result.add(expr1)return result
>>> {x + 3 for x in range(4)}{3, 4, 5, 6}
匿名函数示例:
>>> 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]
格式化字符串的示例,例如下列命令行echo命令:
num="3"; printer="HP Laserjet"echo "I just printed ${num} pages to the printer ${printer}"
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 关系型数据库".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 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)
>>> menu_item("egg","bacon")egg, bacon, and spamegg, bacon, and spamegg, 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 decoratordef 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()I'm invincible!My favourite colour is blue.None shall pass.
在类中调用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 = objectc = typeclass M(c): passclass A(metaclass=M): passclass B(A): passb = 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