• 40. 模块和导入

    40. 模块和导入 模块是 Python 代码加载、命名空间隔离和重用的基本单元。在 CPython 中,模块既是语言级对象,也是导入系统中的运行时记录。 在Python层面,模块是执行后得到的: python import math import os import json 每个导入的名称都绑定到模块对象、包对象、函数、类或其他导出对象。在CPython层面,导入是一个协调的过程,涉及字节码指令、导入钩子、模块规范、加载器、查找器、 sys.modules 、包路径、文件系统查找、字节码缓存、导入锁和模块执行。 导入系统不是简单的文件包含机制。它是一个运行时协议。 40.1 什么是模块 模块是类型的对象 module 。```python import sys print(type(sys)) print(sys. name ) 输出: text <class 'module'> sys 模块对象拥有一个字典。该字典是模块的全局命名空间。 python import math print(math. dict ["pi"]) print(math. dict ["sqrt"]) 对于名为 ` config . py ` : ``` python debug = True port = 8080 def connect (): return port ``` CPython 创建一个模块对象,准备其命名空间,在该命名空间内执行编译后的代码对象,并将生成的绑定保留在 ` config…

  • 44.类和元类

    44.类和元类 类是一个运行时对象,它创建实例、存储属性、参与继承并通过 Python 对象模型定义行为。在 CPython 中,类是一个对象,其类型通常为 type 。 元类是类的类。它控制类对象的创建、初始化、表示和调用方式。 对于普通班级:```python id="g3fkzi" class User: pass print(type(User)) 输出: text id="iqt3cc" <class 'type'> ```这意味着 User 是一个对象,它的类型是 type 。 44.1 类是对象 类定义创建一个类对象。```python id="8zc5m6" class User: name = "anonymous" def hello(self): return "hello" 执行后,`User`是绑定在周围名称空间中的普通名称。 python id="rx6c1m" print(User) print(type(User)) print(User. name ) print(User. dict ) 类对象存储以下属性: text id="xxewj0" name qualname module dict bases mro methods descriptors class variables annotations ## 44.2 类定义即执行 类体是可执行代码。 ``` python id…

  • 42. 导入锁

    42. 导入锁 导入锁是防止不安全并发导入的同步机制。在 CPython 中,导入不仅仅是名称查找。他们可能会创建模块对象、改变 sys.modules ,执行任意Python代码,初始化扩展模块,更新包属性,编译源文件,读取字节码缓存,以及运行包初始化代码。 如果没有锁定,两个线程可以同时导入同一模块并观察到不一致的模块状态。 导入锁的存在是因为导入是执行,而执行会改变共享的运行时状态。 42.1 为什么导入需要锁定 考虑这个模块:```python id="ez8v8a" cache.py print("initializing cache") items = {} def get(key): return items[key] 现在考虑两个线程同时执行此操作: python id="2pklaf" import cache 如果没有同步,两个线程可能: text id="oy5qmp" create a module object insert or overwrite sys.modules["cache"] execute cache.py initialize items twice observe a partially initialized module bind different module objects ## 42.2 导入改变全局运行时状态 导入涉及共享状态。 重要的共享结构包括: ```text id="yxk2bl" sys.modules sys.meta_path sys.path sys.path_hooks sys.path_importer_cache parent package attributes module dictionaries…

  • 43. 描述符

    43. 描述符 描述符是一个控制另一个对象的属性访问的对象。描述符是 Python 对象模型背后的主要机制之一。他们解释了方法如何绑定到实例,如何 property 工作原理,如何 staticmethod 和 classmethod 工作原理、槽的工作原理以及有多少 CPython 级别的类型操作连接到 Python 级别的语法。 在语言级别,描述符是定义以下一个或多个方法的任何对象: python id="x7hcrg" __get__(self, obj, objtype=None) __set__(self, obj, value) __delete__(self, obj) 一个对象与 __get__ 是一个描述符。 一个对象与 __set__ 或者 __delete__ 是一个数据描述符。 非数据描述符和数据描述符之间的区别控制着查找优先级。 43.1 为什么描述符存在 Python 属性访问看起来很简单: python id="96l8i5" obj.name 但这个表达式并不意味着“读取一个名为 name 从记忆中。” 这意味着:```text id="drqc0j" ask the object's type how attribute lookup works search descriptors and dictionaries in a defined order possibly call descriptor methods return the resulting…

  • 41. 套餐

    41. 包 包是一个可以包含其他模块的模块。在 CPython 中,包不是一个单独的对象类别。它仍然是一个模块对象,但它具有导入元数据,告诉导入系统在哪里查找子模块。 在Python级别,这个目录可以是一个包: text app/ __init__.py config.py server.py 您可以将其导入为: python import app import app.config from app.server import run 重要的规则很简单:```text A package is a module with submodule search locations. ## 41.1 包是模块 包对象具有类型 ` module ` 。 ``` python import email print ( type ( email )) print ( email . __name__ ) ``` 输出: ``` text < class 'module' > email ``` 就像任何其他模块一样,包也有一个模块字典。 ``` python import email…