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 mymod
>>> from mymod import Hello_World
>>> Hello_World()
Hello_World mymod
但我在想,Python中有没有人们通常使用的标准方法来实现自动加载呢?
其次,想问问有经验的Python开发者,这种做法是好是坏?我算是有点经验的Python开发者,我觉得这个方法挺有用的,但又觉得有点边缘,所以想知道这是否可以被视为好习惯、坏习惯或者其他。
3 个回答
-1
不,我觉得这样做没什么用。
为什么要为你想从模块中获取的每一个属性都创建一个函数呢?这听起来很让人困惑。感觉就像是有些新函数是凭空出现的,所以你得深入了解实现细节才能明白发生了什么。而这一切都没有带来任何语法上的好处。
即使你有很好的理由这样做,为什么还要用模块呢?为什么要把你的类实例注册到sys.modules
里?在Python中,让事物看起来不是它们本来的样子是被不赞成的。
除非你是故意让代码变得复杂,否则我看不出这样做的理由。
2
关于用类来模拟模块的问题:
没错,这种功能并不是偶然出现的。从2.x版本早期就有这个功能,并且在3.x版本中也依然有效。
关于懒加载的问题:
有好几种方法可以实现懒加载,每种方法都有点神秘。使用模块模拟器是一种不错的方法。