I studied the dynamic "plugin loading" for python and noticed a not very problematic, but an interesting difference between import module and from package import module .
I created a test script consisting of four files (similar to my own setup, for which I want to achieve)
The file tree looks like this:
- test (main package)
- sup (package, folder with plugins)
- __ __ INIT. RU
- uber.py (plugin)
- __ __ INIT. RU
- bar.py ('main'-program)
- foo.py (an object that requires dynamically added functionality)
- poo.py (decorator)
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
I have two versions of bar.py, this does not work:
import foo f = foo.Foo() f.aFunction("print goes here")
It works:
from test import foo f = foo.Foo() f.aFunction("print goes here")
The only difference between the two columns is import. One of them is relative, the other is not. But relative does not work, and absolute does. Can someone reproduce this on their machine and can give some explanation why this is happening?
Update
Thought it would be useful to mention my python version as well: Using the regular version of python 2.7.2 x86
Update
The output of the "wrong" 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'
The output of the "correct" bar.py:
before: False after : True print goes here