这是我以前的学习笔记,所以内容上收集了一些初级python教材里不太提到的注意点。先发到博客上给初学者看看,之后有时间会单独写文章针对某些语句进行更详细的说明。
注:多条简单语句可以存在于同一行内并以分号分隔。
表达式语句
表达式语句用于计算和写入值(大多是在交互模式下),或者(通常情况)调用一个过程 (过程就是不返回有意义结果的函数;在 Python 中,过程的返回值为 None
赋值语句
赋值语句用于将名称(重)绑定到特定值,以及修改属性或可变对象的成员项
对象赋值的目标对象可以包含于圆括号或方括号内,具体操作按以下方式递归地定义。
-
如果目标列表为后面不带逗号、可以包含于圆括号内的单一目标,则将对象赋值给该目标。
-
否则:
如果目标列表包含一个带有星号前缀的目标,这称为“加星”目标:则该对象至少必须为与目标列表项数减一相同项数的可迭代对象。 该可迭代对象前面的项将按从左至右的顺序被赋值给加星目标之前的目标。 该可迭代对象末尾的项将被赋值给加星目标之后的目标。 然后该可迭代对象中剩余项的列表将被赋值给加星目标(该列表可以为空)。 - 该对象必须为具有与目标列表相同项数的可迭代对象,这些项将按从左至右的顺序被赋值给对应的目标。增强赋值语句
增强赋值语句
增强赋值语句就是在单个语句中将二元运算和赋值语句合为一体:
增强赋值语句例如 x += 1
可以改写为 x = x + 1
获得类似但并非完全等价的效果。 在增强赋值的版本中,x
仅会被求值一次。 而且,在可能的情况下,实际的运算是 原地 执行的,也就是说并不是创建一个新对象并将其赋值给目标,而是直接修改原对象。
不同于普通赋值,增强赋值会在对右手边求值 之前 对左手边求值。 例如,a[i] += f(x)
首先查找 a[i]
,然后对 f(x)
求值并执行加法操作,最后将结果写回到 a[i]
。
带标注的赋值语句
带标注赋值就是在单个语句中将变量或属性标注和可选的赋值语句合为一体
与普通赋值语句的差别在于仅允许单个目标。
在 3.8 版更改: 现在带有标注的赋值允许在右边以同样的表达式作为常规赋值。 之前某些表达式(例如未加圆括号的元组表达式)会导致语法错误。
assert
语句
assert 语句是在程序中插入调试性断言的简便方式:
Pass语句
这是一个空操作,表示什么都不会发生,它适合当语法上需要一条语句但并不需要执行任何代码时。
del
语句
删除语句,注意删除是递归定义的,与赋值的定义方式非常类似。
return 语句
return 在语法上只会出现于函数定义所嵌套的代码,不会出现于类定义所嵌套的代码。
如果提供了表达式列表,它将被求值,否则以 None 替代。
当 return 将控制流传出一个带有 finally 子句的 try 语句时,该 finally 子句会先被执行然后再真正离开该函数。
在一个生成器函数中,return 语句表示生成器已完成并将导致 StopIteration 被引发。 返回值(如果有的话)会被当作一个参数用来构建 StopIteration 并成为 StopIteration.value 属性。
在一个异步生成器函数中,一个空的 return 语句表示异步生成器已完成并将导致 StopAsyncIteration 被引发。 一个非空的 return 语句在异步生成器函数中会导致语法错误。
yield
语句
yield 表达式和语句仅在定义生成器函数时使用,并且仅被用于生成器函数的函数体内部。
break 语句
break 在语法上只会出现于 for 或 while 循环所嵌套的代码,但不会出现于该循环内部的函数或类定义所嵌套的代码。
它会终结最近的外层循环,如果循环有可选的 else 子句,也会跳过该子句。
如果一个 for 循环被 break 所终结,该循环的控制目标会保持其当前值。
当 break 将控制流传出一个带有 finally 子句的 try 语句时,该 finally 子句会先被执行然后再真正离开该循环。
continue 语句
continue 在语法上只会出现于 for 或 while 循环所嵌套的代码中,但不会出现于该循环内部的函数或类定义中。 它会继续执行最近的外层循环的下一个轮次。
当 continue 将控制流传出一个带有 finally 子句的 try 语句时,该 finally 子句会先被执行然后再真正开始循环的下一个轮次。
import 语句
一个模块所定义的 公有名称 是由在模块的命名空间中检测一个名为 __all__ 的变量来确定的;如果有定义,它必须是一个字符串列表,其中的项为该模块所定义或导入的名称。
如果 __all__ 没有被定义,则公有名称的集合将包含在模块的命名空间中找到的所有不以下划线字符 ('_') 打头的名称。 __all__ 应当包括整个公有 API。 它的目标是避免意外地导出不属于 API 的一部分的项
当指定要导入哪个模块时,你不必指定模块的绝对名称。 当一个模块或包被包含在另一个包之中时,可以在同一个最高层级包中进行相对导入,而不必提及包名称。类似linux的路径
global 语句
global 语句是作用于整个当前代码块的声明。
在 global 语句中列出的名称不得在同一代码块内该 global 语句之前的位置中使用。
在 global 语句中列出的名称不能被定义为形式参数,也不能被作为 with 语句或 except 子句的目标,以及 for 循环的目标列表、class 定义、函数定义、import 语句或变量标注等等。
CPython 实现细节: 当前的实现并未强制要求所有的上述限制,但程序不应当滥用这样的自由,因为未来的实现可能会改为强制要求,并静默地改变程序的含义。
nonlocal 语句
nonlocal 语句会使得所列出的名称指向之前在最近的包含作用域中绑定的除全局变量以外的变量。
这种功能很重要,因为绑定的默认行为是先搜索局部命名空间。 这个语句允许被封装的代码重新绑定局部作用域以外且非全局(模块)作用域当中的变量。
nonlocal声明了将要在一个嵌套的作用域中修改的名称。
在声明nonlocal名称的时候,必须已经存在于该嵌套函数的作用域中,它们只可能存在于一个嵌套的函数中,并且不能由一个嵌套的def中的第一次赋值创建。
nonlocal只在一个函数内有意义。
type 语句
type 语句声明一个类型别名
raise 语句
如果没有提供表达式,则 raise 会重新引发当前正在处理的异常,它也被称为 活动的异常。 如果当前没有活动的异常,则会引发 RuntimeError 来提示发生了错误。
否则的话,raise 会将第一个表达式求值为异常对象。 它必须为 BaseException 的子类或实例。 如果它是一个类,当需要时会通过不带参数地实例化该类来获得异常的实例。
异常的 类型 为异常实例的类,值 为实例本身。
当有异常被引发时通常会自动创建一个回溯对象并将其关联到它的 __traceback__ 属性,该属性是可写的。
回溯对象是指在编程中,当发生错误或异常时,程序可以追踪和记录错误发生的位置和上下文信息的数据结构或对象。它可以帮助开发人员识别和调试问题,并提供有关错误发生原因的详细信息。回溯对象通常包含调用堆栈、变量值和其他相关的调试信息,以帮助开发人员定位和解决问题。
你可以创建一个异常并使用 with_traceback() 异常方法(该方法将返回同一异常实例,并将回溯对象设为其参数)直接设置自己的回溯对象。
跟异常有关的一些其他知识点:
在Python中,__cause__属性是异常对象的一个属性,用于指示引发当前异常的原因异常。当一个异常被另一个异常引发时,__cause__属性可以用来追踪异常之间的关系。它可以包含一个引发当前异常的原因异常对象,或者为None表示没有明确的原因异常。通过访问__cause__属性,开发人员可以获取有关异常链的更多信息,以便进行调试和错误处理。
当已经有一个异常在处理时如果有新的异常被引发则类似的机制会隐式地起作用。 异常可以通过使用 except 或 finally 子句或是 with 语句来处理。 之前的异常将被关联至新异常的 __context__ 属性。
在Python中,__context__属性是异常对象的一个属性,用于指示当前异常的上下文异常。当一个异常被另一个异常捕获并重新引发时,__context__属性可以用来指示被捕获的异常对象。它可以包含一个引发当前异常的上下文异常对象,或者为None表示没有上下文异常。
上下文异常是指在程序执行过程中,某个异常被另一个异常所引发的情况。当一个异常发生时,如果在处理该异常的过程中又发生了另一个异常,那么后者就被称为上下文异常。
在Python中,finally子句是用于定义在无论是否发生异常都必须执行的代码块。它通常与try和except语句一起使用,用于确保在发生异常时也能执行一些必要的清理操作。
无论是否发生异常,finally子句中的代码都会被执行。它常用于释放资源、关闭文件、断开数据库连接等必要的清理操作,以确保程序在任何情况下都能正常结束并保持良好的状态。
需要注意的是,finally子句是可选的,可以省略。但如果使用了finally子句,它必须在try和except之后出现,并且只能有一个finally子句。