在Python中自动加载

2024-06-17 19:39:14 发布

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

在过去,我使用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
>>> from mymod import Hello_World
>>> Hello_World()
Hello_World

但让我印象深刻的是,在python中有没有一种标准的自动加载方法?

其次,对于有经验的python开发人员来说,一个问题是“这对您来说是好的还是坏的做法”?我是一个相当有经验的python开发人员,我觉得它非常有用,但我觉得它是一个边界,我对它是否可以被视为良好实践、不良实践或类似的东西很感兴趣。

谢谢!


Tags: nameimportselfmoduleshelloworldinitdef
3条回答

不,我觉得那没用。

为什么要为试图从模块中获取的每个属性动态创建函数?我觉得很困惑。似乎新的函数是由magic创建的,因此必须深入了解实现以了解发生了什么。所有这些都没有语法上的好处。

即使你有充分的理由这么做,为什么要用一个模块呢?为什么要在sys.modules中注册类实例?我认为,在python中,让事物看起来不像是它们的东西是不受欢迎的。

除非你故意混淆代码,否则我不明白为什么有人会这么做。

“惰性导入”可以构建在PEP 302中指定的“导入挂钩”之上,现在可以完全实现。PEP 369过去用于覆盖“惰性导入”和导入后挂钩,但后来被简化,现在只覆盖导入后挂钩;不过,您可能对original draft感兴趣。

通过meta_path钩子可以在this recipe中找到一个很好的“惰性导入”实现。

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

是的,功能不是偶然的。它从2.x系列的早期就出现了,在3.x系列中仍然有效。

要回答延迟加载的问题:

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

相关问题 更多 >