Python执行模型

综述

Code Blocks

代码块:作为一个单元执行的一段python文本,代码块构成python 程序

  • 模块、函数体、类定义
  • 交互式输入的每条命令
  • 作为标准输入、命令行参数发送给解释器的脚本文件
  • 脚本命令
  • 传递给eval()exec()的字符串参数
  • 代码块在执行帧中执行,执行帧包含某些用于调试的管理信息 并决定代码块执行完成后操作

NamingBinding

Binding of Names

  • 名称:用于指代对象,通过名称绑定操作引入
  • 名称绑定方法

    • 传递参数
    • import语句
      • from ... import *会绑定被导入模块中定义的所有 公有名称(仅在模块层级上被使用)
    • 类、函数定义
    • 以标识符为目标的赋值
    • for循环开头、withexcept子句的as之后

    • del语句的目标也被视为绑定,虽然实际语义为解除名称 绑定

  • 变量类型

    • 局部变量:绑定在代码块中的名称,且未声明为nonlocal 、或global
    • 全局变量:绑定在模块层级的名称
      • 模块代码块中变量既为全局变量、也是局部变量
    • 自由变量:在代码块中使用但未在其中定义的变量
  • 自由变量不同于闭包变量,函数闭包变量__closure__要求 自由变量来自于父函数作用域

Scope

作用域:定义了代码块中名称的可见性

  • 名称的作用域包含

    • 定义该变量代码块
    • 定义变量代码块所包含的代码块 (除非被包含代码块中引入对该名称不同绑定)
  • 名称作用域虽然包括定义变量代码块所包含的代码块

    • 可以直接访问变量
    • 但修改变量必须使用globallocal等声明
  • 在代码块内任何位置进行名称绑定,则代码块内所有对该名称 的使用被认为是对代码块的引用

    • python没有声明语法,则代码块中局部变量可通过,在整个 代码块文本中扫描名称绑定来确定
  • 模块作用域在模块第一次被导入时创建

Resolution of Names

  • 若名称在代码块中被使用,会由包含它的最近作用域来解析

  • 若名称完全无法找到将raise NameError

  • 若当前作用域为函数作用域,且名称指向局部变量,若名称被 绑定值前被被使用将raise UnboundLocalErrorUnboundLocalErrorNameError子类)

  • (代码块)环境:对代码块可见的所作用域集合

global

  • global指定名称的使用是对最高层级命名空间中该名称 绑定的引用

    • 全局命名空间:包含代码块的模块命名空间
    • 内置命名空间:builtins模块的命名空间
  • global语句与同一代码块中名称绑定具有相同作用域

    • 若自由变量最近包含作用域中有global语句,其也会被 当作全局变量
  • global语句须在名称使用之前声明

nonlocal

  • nonlocal使得相应名称指向最近包含函数作用域的中绑定的 变量

  • 指定名称不存在于任何包含函数作用域则raise SyntaxError

内置命名空间

  • 与代码块执行相关联的内置命名空间实际上是通过其在全局命名 空间中搜索名称__builtins__找到,一般是字典、模块 (此时使用模块的命名空间字典)

  • 默认情况下

    • __main__模块中:__builtins__为内置模块builtins
    • __main__模块中:__buitlins__builtins模块 自身的字典别名

动态特性

  • 自由变量的名称解析

    1
    2
    3
    4
    5
    6
    i = 0
    def f():
    print(i)
    i = 42
    f()
    # 打印`42`
    • 发生在运行时,而不是编译时
    • 在全局命名空间中,而不是最近包含命名空间中

eval()exec()

  • eval()exec()没有对完整环境的访问权限来解析名称

    • 有可选参数用于重载全局、局部命名空间
    • 若只指定一个命名空间,则会同时作用于两者

  • 类中名称解析遵守大部分情况下同普通规则,但 未绑定局部变将在全局命名空间中搜索

  • 类定义的命名空间__dict__会成为类的属性字典

  • 类代码块中定义的名称的作用域会被限制在类代码块中,不会 扩展到方法代码块中,包括推导式、生成器表达式

    1
    2
    3
    class A:
    a = 42
    b = list(a + i for i in range(10))

Exception

异常:中断代码块的正常控制流程以便处理错误、其他异常条件的 方式

  • 在错误被检测到的位置引发

    • 解释器检测到运行时错误时错误
    • raise语句显式引发
  • 可被当前包围代码块、任何直接或间接主调代码块捕获、处理

    • try...except指定错误处理,finally子句清理代码
    • 异常通过实例标识、根据器类型选择执行except子句
  • 错误处理采用“终止”模型

    • 异常处理器可以找出发生的问题,在外层继续执行
    • 但不能修复错误的根源,并重试失败操作
    • 异常完全未被处理时,解释器会终止程序执行、或返回交互 模式循环,并打印栈回溯信息,除非为SystemExit异常
  • 异常实例可以携带关于异常状态的额外信息

    • 异常信息不是python API一部分,内容可能在不同python 版本间不经警告的改变
Author

UBeaRLy

Posted on

2019-06-11

Updated on

2021-08-02

Licensed under

Comments