防止 Python 包重新导出导入的名称 [英] Prevent Python packages from re-exporting imported names

查看:49
本文介绍了防止 Python 包重新导出导入的名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Python 包中,我有文件结构

包/__init__.py导入_me.py

文件 import_me.py 被认为提供了功能片段:

导入重新导入系统定义你好():经过

以便package.import_me.hello可以通过import动态导入.不幸的是,这也允许将 resys 导入为 package.import_me.repackage.import_me.sys, 分别.

有没有办法防止import_me.py中导入的模块再次被重新导出?最好这应该超越名称修改或下划线前缀的导入模块,因为在我的情况下,它可能会在某些情况下造成安全问题.

解决方案

没有简单的方法可以禁止从模块导入全局名称;Python 根本不是那样构建的.

虽然如果您编写自己的 __import__ 函数并隐藏内置函数,您可能会实现令人生畏的目标,但我怀疑时间和测试的成本是否值得,也不完全有效.

您可以做的是导入带有前导下划线的依赖模块,这是用于传达实现细节,使用风险自负"的标准 Python 习惯用法:

import re as _re将 sys 导入为 _sys定义你好():经过

注意

虽然只是删除导入的模块作为不允许导入它们的方式似乎可行,但实际上并没有:

导入重新导入系统定义你好():系统打印('你好')德尔雷删除系统

然后导入并使用hello:

<预><代码>>>>导入 del_mod>>>del_mod.hello()回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中文件del_mod.py",第 5 行,在 hello系统NameError: 全局名称 'sys' 未定义

In a Python package, I have the file structure

package/
    __init__.py
    import_me.py

The file import_me.py is thought to provide snippets of functionality:

import re
import sys

def hello():
    pass

so that package.import_me.hello can be imported dynamically via import. Unfortunately, this also allows to import re and sys as package.import_me.re and package.import_me.sys, respectively.

Is there a way to prevent the imported modules in import_me.py to be re-exported again? Preferably this should go beyond name mangling or underscore-prefixing imported modules, since in my case it might pose a security problem under certain instances.

解决方案

There is no easy way to forbid importing a global name from a module; Python simply is not built that way.

While you could possibly achieve the forbidding goal if you wrote your own __import__ function and shadowed the built-in one, but I doubt the cost in time and testing would be worth it nor completely effective.

What you can do is import the dependent modules with a leading underscore, which is a standard Python idiom for communicating "implementation detail, use at your own risk":

import re as _re
import sys as _sys

def hello():
    pass

Note

While just deleting the imported modules as a way of not allowing them to be imported seems like it might work, it actually does not:

import re
import sys

def hello():
    sys
    print('hello')

del re
del sys

and then importing and using hello:

>>> import del_mod
>>> del_mod.hello()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "del_mod.py", line 5, in hello
    sys
NameError: global name 'sys' is not defined

这篇关于防止 Python 包重新导出导入的名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆