在python中导入钩子

2024-06-17 10:41:06 发布

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

你好,我想在python的副本中实现一个小的库访问控制,我想知道是否有某种方法可以在导入系统上创建一个钩子,以便我的程序可以在每次导入时检查一个文件,如果该程序有权导入该库。 我看到了一些关于sys库和pep302(https://www.python.org/dev/peps/pep-0302/)的东西,但我不明白。在


Tags: 文件方法httpsorgdev程序系统www
1条回答
网友
1楼 · 发布于 2024-06-17 10:41:06

您可以通过实现自己的自定义导入加载器对象来更改模块的导入。文档的起点可以在这里找到:https://docs.python.org/3/library/importlib.html

您需要做的是创建一个加载器,它将作用于您要检查的包,然后加载它们,或者引发所需的异常。如果模块不在您的访问控制列表中,您应该返回None,这将使导入机器正常加载它们。我已经创建了这类功能的最小示例,您可以从中开始并扩展以构建所需的功能。在

import sys
import importlib

class ImportInterceptor(importlib.abc.Loader):
    def __init__(self, package_permissions):
        self.package_permissions = package_permissions

    def find_module(self, fullname, path=None):
        if fullname in self.package_permissions:
            if self.package_permissions[fullname]:
                return self
            else:
                raise ImportError("Package import was not allowed")

    def load_module(self, fullname):
        sys.meta_path = [x for x in sys.meta_path[1:] if x is not self]
        module = importlib.import_module(fullname)
        sys.meta_path = [self] + sys.meta_path
        return module


if not hasattr(sys,'frozen'):
    sys.meta_path = [ImportInterceptor({'textwrap': True, 'Pathlib': False})] + sys.meta_path


import textwrap

print(textwrap.dedent('    test'))
# Works fine

from pathlib import Path
# Raises exception

请注意,加载程序从系统元路径加载包时。这是为了避免一个无限循环,在这个循环中,每次试图“真正”加载模块时,它都会不断地调用自己。在

相关问题 更多 >