python - 在python中导入钩子
问题描述
您好,我想在我的 python 副本中为自己实现一个小库访问控制,我想知道是否有某种方法可以在导入系统上创建一个 Hook,以便我的程序可以在每次导入时检查文件如果该程序有权导入该库。我看到了一些关于 sys 库和 pep 302(https://www.python.org/dev/peps/pep-0302/)的东西,但我不明白。
解决方案
您可以通过实现自己的自定义导入加载器对象来更改模块的导入。可以在此处找到文档的起点: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
请注意,加载程序在加载包时会将自身从 sys.meta_path 中删除。这是为了避免无限循环,每次尝试“真正”加载模块时,它都会不断调用自己。
推荐阅读
- java - 为什么我的结果集会出现错误?
- reactjs - React 组件组合的正确或有效方法是什么?
- php - 我如何在 laravel 中使用多个数据库,比如一组一个数据库?
- android - Android ConnectivityManager onAvailable 有时未返回
- node.js - 我们如何在一个项目中同时使用“扩展”真或假
- java - 如何修复 Fortify Path Manipulation (Input Validation and Representation, Data Flow) 漏洞
- postgresql - 我在两列(楼层ID和票证)的弹簧启动服务中制作了复合键
- sql-server - 如何避免在 Powershell 中使用 SMO 对象的系统数据库?
- c# - 如何使用 c# 生成 UUID 版本 4
- join - 如何加入同一表中存在的列