如何在不导入的情况下模仿Python模块?

皮埃尔·丹尼斯

我曾尝试为Python 3开发一个“模块扩展器”工具,但存在一些问题。

想法如下:对于给定的Python脚本main.py,该工具expanded_main.py通过将每个import语句替换为导入模块的实际代码来生成功能上等效的Python脚本这假设导入的Python源代码是可访问的。为了正确地完成这项工作,我使用了astPython的内置模块以及astor允许将AST转回Python源的第三方工具。这种导入扩展器的目的是能够将脚本编译成一个字节码块,因此Python VM不必处理模块的导入(例如,这可能对MicroPython有用)。

最简单的情况是以下语句:

from import my_module1 import *

为了对此进行转换,我的工具会寻找一个文件my_module1.py,并用该文件的内容替换import语句。然后,expanded_main.py可以访问中定义的任何名称my_module,就好像该模块是按常规方式导入的一样。我不在乎可能揭示窍门的细微副作用。另外,为简化起见,我将其from import my_module1 import a, b, c视为先前的导入内容(带星号),而无需担心可能的副作用。到现在为止还挺好。

现在这是我的观点。您如何处理这种进口方式:

import my_module2

我的第一个想法是通过创建一个与模块同名的类并复制缩进的Python文件的内容来模仿这一点:

class my_module2:
    # content of my_module2.py
    …

这实际上在许多情况下都有效,但是,令人遗憾的是,我发现它有几个故障:其中之一是它的功能失败,该函数具有引用模块中定义的全局变量的主体。例如,考虑以下两个Python文件:

# my_module2.py 
g = "Hello"
def greetings():
    print (g + " World!")

# main.py
import my_module2
print(my_module2.g)
my_module2.greetings()

执行时,main.py打印"Hello""Hello World!"现在,我的扩展器工具将生成以下内容:

# expanded_main.py
class my_module2:
    g = "Hello"
    def greetings():
        print (g + " World!")
print(my_module2.g)
my_module2.greetings()

在执行时expanded_main.py,第一个打印语句为OK("Hello"),但greetings函数引发异常:NameError: name 'g' is not defined实际上发生的是

  • 模块中 my_module2g是一个全局变量,
  • 类中 my_module2g是一个类变量,应称为my_module2.g

当您在中定义函数,类等时,my_module2.py并希望在相同的其他函数,类中引用它们时,也会发生其他类似的副作用my_module2.py

知道如何解决这些问题吗?

除了类之外,还有其他的Python结构可以模仿模块吗?

最后说明:我知道该工具应注意嵌套导入(递归)的1°,同一模块可能多次导入的2°。我不希望在这里讨论这些主题。

客人

您可以在函数范围内执行模块的源代码,特别是实例方法。然后,可以通过__getattr__在相应的类上进行定义并保留初始函数的副本来使属性可用locals()这是一些示例代码:

class Importer:
    def __init__(self):

        g = "Hello"

        def greetings():
            print (g + " World!")

        self._attributes = locals()

    def __getattr__(self, item):
        return self._attributes[item]


module1 = Importer()
print(module1.g)
module1.greetings()

通过使用实例替换它们,可以自然地处理嵌套导入Importer重复导入也不是问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在不导入模块的情况下运行模块?

如何在不导入的情况下从已编译的Python模块获取函数名?

如何在不导入的情况下检查python模块是否存在

如何在不导入其他模块的情况下更改python中文本的颜色?

如何在不更改导入的情况下将Python 3模块更改为软件包?

在不运行.Py的情况下导入Python模块

如何在不导入Julia的功能的情况下加载软件包模块

如何在不导入外部模块(matplotlib除外)的情况下绘制运行平均值?

如何在不使用导入的情况下导入导入其他模块的模块*

Python 3.4:如何在给定完整路径的情况下导入模块?

如何在不真正导入的情况下使用长python模块包的别名?

如何在不使用任何模块或导入的情况下使用 python 字典创建 CSV 表

如何在不执行python -m的情况下使用相对导入?

如何在不导入每个类的情况下创建具有不同类的 python 包

如何在不导入的情况下从python文件获取函数

如何在不构建模块的情况下向Python公开C ++类

可以在不导入的情况下使用Python的标准库的Python写模块吗?

没有在Python中导入的情况下,如何在全局名称空间中使用内置模块的内容?

没有类型定义的情况下如何在Typescript中导入节点模块?

如何在导入所有模块的情况下启动Powershell会话?

如何在给定完整路径的情况下导入模块?

如何在不引起 TypeScript 警告的情况下引用动态导入的模块内容?

如何在不进行更改导入的情况下从模块运行脚本?

如何在不初始化权重的情况下导入经过训练的模型

XSD:如何在不导入元素的情况下从外部 XSD 引用类型?

Django:如何在不导入模型的情况下用_meta指定verbose_name?

如何在不导入库的情况下获得 VS Code/打字稿自动完成

Vue:vuetify如何在不导入的情况下使其组件可用?

如何在不导入pollyfills的情况下以角度显示不支持的Internet Explorer