15

过去,我使用 Perl 的 AUTOLOAD 工具来实现将符号延迟加载到命名空间中,并希望在 python 中具有相同的功能。

传统上,您似乎能够获得的最接近的是使用一个类和一个__getattr__类来实现这种事情。但是,我也尝试过在 中翻找sys.modules,并想出了这个:

# mymod.py
def greet(greeting="Hello World"):
   print greeting

class Autoload(object):
    def __init__(self, __name__):
        super(Autoload, self).__init__()
        self.wrapped_name = __name__
        self.wrapped = sys.modules[__name__]
    def __getattr__(self, name):
        try:
            return getattr(self.wrapped, name)
        except AttributeError:
            def f():
                greet(name+" "+self.wrapped_name)
            return f

if __name__ != "__main__":
    import sys
    sys.modules[__name__] = autoload(__name__)

从用户的角度来看,这确实以我想要的方式工作:

~> python
Python 2.5.1 (r251:54863, Jan 10 2008, 18:01:57)
[GCC 4.2.1 (SUSE Linux)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mymod
>>> mymod.hello()
hello mymod
>>> from mymod import Hello_World
>>> Hello_World()
Hello_World mymod

但这让我印象深刻——人们是否倾向于使用标准方法在 python 中自动加载?

其次,对于有经验的 python 开发人员来说,一个问题真的是“这对你来说是好还是坏的做法”?我是一位经验丰富的 Python 开发人员,它让我觉得它真的很有用,但它让我觉得它是边缘性的,并且对这是否可以被视为好的做法、坏做法或类似做法感兴趣。

4

3 回答 3

10

“惰性导入”可以构建在PEP 302中指定的“导入钩子”之上,现在已完全实现。PEP 369 曾经涵盖“惰性导入”以及导入后挂钩,但此后已简化,现在仅涵盖导入后挂钩;不过,您可能对原始草稿感兴趣。

meta_path在这个秘籍中可以找到通过钩子实现“惰性导入”的好方法

于 2009-06-21T18:24:23.827 回答
2

要回答使用类来模拟模块的问题:

是的,该功能并非偶然。它从 2.x 系列的早期就已经存在,并且在 3.x 系列中仍然有效。

回答延迟加载的问题:

有几种方法可以做到,每一种都会有点神秘。使用模块模仿器是一种很好的方法。

于 2017-05-05T19:06:20.677 回答
-1

不,我认为这没有用。

为什么要为您尝试从模块中获取的每个属性动态创建一个函数?对我来说似乎很困惑。似乎新功能正在由魔法创建,因此必须深入研究实现以了解正在发生的事情。所有这些都没有语法上的好处。

即使你有充分的理由这样做,为什么要使用模块呢?为什么要在 中注册您的类实例sys.modules?我认为在 python 中使事物看起来不是它们所不赞成的。

除非您故意混淆代码,否则我不明白为什么要这样做。

于 2009-06-22T11:18:48.183 回答