Import all classes in directory?
我找到了这个,但这不是我想做的。
我想导入目录中所有文件中的所有类。基本上,我想替换这个:
1 2 3
| from A import *
from B import *
from C import * |
有一些动态的,这样我就不会每次添加另一个文件时都继续编辑我的__init__.py。
glob解决方案似乎等同于
1 2 3
| import A
import B
import C |
号
这完全不一样。
- 你想用这个实现什么?
- 这个答案有什么问题:stackoverflow.com/questions/1057431/…?
- @伊格纳西奥:最后一句。我有大约15种型号,而且所有的都需要进口。当这可以通过编程实现时,我不需要继续更新__init__.py是没有意义的。
- 这就是原因,不是原因。
- @伊格纳西奥:你说不通。为什么?少打字。不易出错。不会忘记更新文件。节省时间。我真的需要证明这一点吗?
- 那么你这样做不是为了拥有插件?
- 显式优于隐式。
- @马克:完全不需要打字,但这并不意味着它不容易出错。事实上,根据AJ的评论,我认为这可能更容易出错。
- @不,没有插件。它不应该是像你把一个文件放进去包含一个插件的地方。一切都将由我来建造。我有很多类,我把它们分成了不同的文件。框架需要在启动时将它们全部加载,这样它就知道它们存在,而且它还使我可以轻松地使用它们,而不必一直导入许多不同的东西。
- @阿杰/格雷格:也许吧。但他们是班级。除非执行,否则它们不太可能引入细微的错误。
您可以这样做,尽管记住isinstance(cls, type)只适用于新样式的类。
1 2 3 4 5 6 7 8 9
| import os, sys
path = os.path.dirname(os.path.abspath(__file__))
for py in [f[:-3] for f in os.listdir(path) if f.endswith('.py') and f != '__init__.py']:
mod = __import__('.'.join([__name__, py]), fromlist=[py])
classes = [getattr(mod, x) for x in dir(mod) if isinstance(getattr(mod, x), type)]
for cls in classes:
setattr(sys.modules[__name__], cls.__name__, cls) |
- 是的,我看到那个答案了,它不起作用。它导入模块,但不导入类。我必须以address.Address的形式访问该文件,而我只需要使用Address就可以访问它。这是有区别的。
- 你应该使用os.path.join(os.path.dirname(__file__), '*.py')而不是os.path.dirname(__file__) +"/*.py"。
- @马克调整了我的答案以反映这一点。
- hrm…关闭。这个'.'.join([pkg, py])需要再提高一级。也就是说,我必须用'.'.join(['shipments', pkg, py])替换它,因为我的项目的根比它高一级。我们不能得到模块的绝对路径,这样就不需要硬编码了吗?
- @马克是的,当然可以,无论如何都应该使用__name__。再调整一下,看看是否对你有用。
- 现在我们在说话!
- 对我来说,ImportError: No module named ...发生在mod = __import__('.'.join([__name__, py]), fromlist=)处。