import语句在何处/如何解析名称“posix”?

2024-06-02 05:00:58 发布

您现在位置:Python中文网/ 问答频道 /正文

当代码使用^{}时,幕后会发生什么(在cpython3.6.0中)?此模块没有__file__属性。在详细模式下启动解释器时,我看到以下行:

import 'posix' # <class '_frozen_importlib.BuiltinImporter'>

它已经存在于新打开的解释器中的sys.modules中,导入它只会将一个名称绑定到现有模块。在

我试图在我的平台上查看os.lstat的实现细节,以确定它是否以及何时使用os.stat。在


Tags: 模块代码importmodules属性ossys模式
1条回答
网友
1楼 · 发布于 2024-06-02 05:00:58

在这里,有比你可能需要的更多的细节。在


posix是一个内置模块。当您听到“内置模块”时,您可能会想到普通的标准库模块,或者您可能会想到用C编写的模块,但是posix比大多数模块更内置。在

posix模块是用C编写的,在^{}中。然而,尽管大多数C模块,甚至是标准库C模块,都被编译成.so或{}文件,并像常规Python模块一样放在导入路径上,posix实际上直接编译到Python可执行文件本身中。在


CPython导入系统的一个内部细节是^{} array

extern struct _inittab _PyImport_Inittab[];

struct _inittab *PyImport_Inittab = _PyImport_Inittab;

这是一个struct _inittabs的数组,它由一个名称和一个用于具有该名称的模块的C模块初始化函数组成。这里列出的模块是内置的。在

这个数组最初被设置为_PyImport_Inittab,它来自Modules/config.c(或{},具体取决于您的操作系统,但这里不是这样)。不幸的是,Modules/config.c是在Python构建过程中从^{}生成的,因此我无法向您显示源代码链接,但以下是我生成文件时的部分内容:

^{pr2}$

{{cd16>模块的初始化可以在这里看到。在


作为导入系统的一部分,当尝试加载模块时,Python要经过sys.meta_path,一个模块列表finders。其中一个查找器负责执行您可能更熟悉的sys.path搜索,但另一个是_frozen_importlib.BuiltinImporter,负责查找posix之类的内置模块。当Python尝试这个finder时,它运行finder的^{}方法:

@classmethod
def find_spec(cls, fullname, path=None, target=None):
    if path is not None:
        return None
    if _imp.is_builtin(fullname):
        return spec_from_loader(fullname, cls, origin='built-in')
    else:
        return None

它使用^{}来搜索PyImport_Inittab中的"posix"名称。搜索会找到名称,因此find_spec返回一个模块规范,表示内置模块的加载程序应该处理创建此模块的事实。(加载程序是spec_from_loader的第二个参数。这里是cls,因为BuiltinImporter既是查找器也是装载器。)

然后,Python运行加载程序的^{}方法来生成模块对象:

@classmethod
def create_module(self, spec):
    """Create a built-in module"""
    if spec.name not in sys.builtin_module_names:
        raise ImportError('{!r} is not a built-in module'.format(spec.name),
                          name=spec.name)
    return _call_with_frames_removed(_imp.create_builtin, spec)

它委托给^{},后者在PyImport_Inittab中搜索模块名并运行相应的初始化函数。在

_call_with_frames_removed(x, y)只是调用x(y),但是part of the import system将它视为一个神奇的指示器,可以从堆栈跟踪中剥离importlib帧,这就是为什么当导入出错时,您永远不会在堆栈跟踪中看到这些帧。)


如果您想了解更多相关的代码路径,您可以查看^{},其中大部分导入实现位于^{},其中大部分C部分实现位于其中)和{a12},这是字节码解释器循环所在的地方,因此也是import语句执行的起点,在它到达进口机械的核心部件之前。在

相关文档包括section of the language reference on the import system,以及政治公众人物451和{a15}。虽然我发现a bit of documentation针对的是在其他程序中嵌入Python的人,但是没有太多关于内置模块的文档,因为他们可能想要修改PyImport_Inittab,还有{a17}列表。在

相关问题 更多 >