【发布时间】:2012-03-22 21:44:44
【问题描述】:
我一直在学习一些用于 python 的动态“插件加载”,并注意到 import module 和 from package import module 之间的一个不是真正的问题而是一个有趣的区别。
我创建了一个包含四个文件的测试脚本(类似于我自己的设置,以实现我想要实现的目标)
文件树如下所示:
- 测试(主包)
- sup(包,插件文件夹)
- __init__.py
- uber.py(插件)
- __init__.py
- bar.py ('main'-program)
- foo.py(需要动态添加功能的对象)
- poo.py(装饰器)
- sup(包,插件文件夹)
poo.py:
from test import foo
def decorate(method):
print "before:", method.__name__ in dir(foo.Foo)
setattr(foo.Foo, method.__name__, method)
print "after :", method.__name__ in dir(foo.Foo)
return method
foo.py:
import os
class Foo(object):
def __init__(self):
self.__loadplugins("sup")
@classmethod
def __loadplugins(cls, plugindir):
for f in os.listdir(os.path.join(os.path.dirname(__file__), plugindir)):
if f.endswith(".py"):
__import__(("%s.%s" % (plugindir, f))[0:-3])
uber.py:
from test import poo
@poo.decorate
def aFunction(self, anArg):
print anArg
我有两个版本的 bar.py,这个不行:
import foo
f = foo.Foo()
f.aFunction("print goes here") # pylint: disable-msg=E1101
这个确实有效:
from test import foo
f = foo.Foo()
f.aFunction("print goes here") # pylint: disable-msg=E1101
两个条之间的唯一区别是导入。一个是相对的,另一个不是。但是相对的不起作用,绝对的起作用。有没有人可以在他的机器上复制这个并且可以对它发生的原因给出某种解释?
更新
认为记下我的python版本会很有用:
使用普通的 python 版本 2.7.2 x86
更新
'错误' bar.py 的输出:
before: False
after : True
Traceback (most recent call last):
File "C:\Users\Daan\workspace\python\mytests\src\test\bar.py", line 6, in <module>
f.aFunction("print goes here") # pylint: disable-msg=E1101
AttributeError: 'Foo' object has no attribute 'aFunction'
“正确”bar.py 的输出:
before: False
after : True
print goes here
【问题讨论】:
-
尝试在您的测试目录中添加一个名为
__init__.py的空文件 -
他们在那里。有点懒得把它们放在那个列表中。但我会特别为你添加它们。
-
你说第一个不起作用是什么意思?如果您看到异常,请包含回溯。
-
@subdir 完成,这是一个相当标准的错误消息。希望这能进一步澄清这一点。
标签: python