英文:
Reload package that was imported with *
问题
我有这个结构:
|-- handler
| |-- __init__.py
| |-- Layer1.py
| |-- Layer2.py
|-- factory.py
|-- main.py
init.py 文件:
from os.path import dirname, basename, isfile, join
import glob
modules = glob.glob(join(dirname(__file__), "*.py"))
__all__ = [basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')]
Layer 文件包括以下样式的类:
@ClassFactory.register(1)
class layer1:
def __init__(self, string):
self.do_something(string)
def do_something(self, string):
something...
在 main.py 文件中,我这样导入:
from handler import *
并调用注册表来运行类函数:
for key, value in sorted(ClassFactory.registry.items()):
value("someValue")
我已经尝试了数小时来在主文件中重新加载 handler 包中的文件。我的目标是能够在解释器仍在运行时手动更改这些文件,然后重新加载它们。我尝试了许多方法,但似乎重新加载 importlib 不会重新加载 handler 中的模块。Ipython.lib 的 deepreload 失败,抛出 NotImplementedError。我无法理解我做错了什么。当我这样做时:
from handler import Layer1
我能够重新加载 Layer1,没有任何问题,但由于我在动态加载目录中加载所有内容,这对我没有帮助,而且必须使用 *。此外,我相当确定,从注册表中加载类会增加另一层复杂性,因为类必须重新注册自己。
感谢您的帮助。
英文:
I have this structure:
|-- handler
| |-- __init__.py
| |-- Layer1.py
| |-- Layer2.py
|-- factory.py
|-- main.py
init.py file:
from os.path import dirname, basename, isfile, join
import glob
modules = glob.glob(join(dirname(__file__), "*.py"))
__all__ = [ basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')]
Layer file includes class that looks as follows:
@ClassFactory.register(1)
class layer1:
def __init__(self,string):
self.do_something(string)
def do_something(self, string):
something...
and in main.py file I import as follows:
from handler import *
And calls the registry to run the class function:
for key, value in sorted(ClassFactory.registry.items()):
value("someValue")
I've been trying for hours to make it reload the files in handler package in main. My goal is to be able to change the files manually and then reload them while the interpreter is still running.
I tried many things, reload of importlib doesn't seem to reload the modules in handler. deepreload of Ipython.lib fails with NotImplementedError. I can't understand what am I doing wrong. When I did:
from handler import Layer1
I was able to reload Layer1 without any issue, but since I'm loading everything in the directory dynamically, it doesn't help and it has to be with *.
Also, I'm pretty sure that the fact that I'm loading the classes from registry adds another layer of complication, since the classes have to re-register themselves.
Would appreciate your help
答案1
得分: 1
代替:
from handler import *
考虑使用类似以下方式:
import inspect, importlib
def import_from(module, dest = None):
if dest is None:
dest = globals()
if hasattr(module, '__all__'):
for item in module.__all__:
dest[item] = getattr(module, item)
return
for name, value in inspect.getmembers(module):
if name.startswith('_'):
continue
dest[name] = value
用法:
import handler
import_from(handler)
### ...and later...
handler = importlib.reload(handler)
import_from(handler)
如果从不同的模块中使用import_from
助手,您需要将该模块的globals()
传递给dest
参数。
英文:
Instead of:
from handler import *
Consider something more like:
import inspect, importlib
def import_from(module, dest = None):
if dest is None:
dest = globals()
if hasattr(module, '__all__'):
for item in module.__all__:
dest[item] = getattr(module, item)
return
for name, value in inspect.getmembers(module):
if name.startswith('_'):
continue
dest[name] = value
Used as:
import handler
import_from(handler)
### ...and later...
handler = importlib.reload(handler)
import_from(handler)
If the import_from
helper is used from a different module, you'll want to pass in that module's globals()
as the dest
argument.
答案2
得分: 1
我最终找到了一个简单的解决方案:
导入部分如下:
import handler
from handler import *
而为了重新加载,我执行了以下操作:
ClassFactory.registry.clear()
for i in handler.__all__:
reload(globals()[i])
这只是简单地访问全局中位于handler包中的所有类名,并在循环中重新加载它们。
英文:
I ended up finding a simple solution:
Imports are
import handler
from handler import *
and for reload I did:
ClassFactory.registry.clear()
for i in handler.__all__:
reload(globals()[i])
Which is simply accesses all the class names in global that are located in handler package and reload them in a loop.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论