3

假设我有这个准系统结构:

project/
  main.py
  providers/
    __init.py__
    acme1.py
    acme2.py
    acme3.py
    acme4.py
    acme5.py
    acme6.py

假设main.py包含(部分):

if complexcondition():
  print providers.acme5.get()

哪里__init__.py是空的并且acme*.py包含(部分):

def get():
  value=complexcalculation()
  return value

如何更改这些文件才能正常工作?

注意:如果答案是“import acme1”、“import acme2”等等__init__.py,有没有办法在不手动列出它们的情况下完成?

4

3 回答 3

6

嘿!两年后,但……也许对某人有帮助

让你的providers/__init__.py像这样:

import os
import glob

module_path = os.path.dirname(__file__)
files = glob.glob(os.path.join(module_path, 'acme*.py'))
__all__ = [os.path.basename(f)[:-3] for f in files]

如果添加或删除任何提供程序/acme*.py,您以后不必更改它

然后from providers import *main.py中使用

于 2011-02-09T10:25:23.187 回答
5

如果我正确阅读了您的问题,那么您似乎并没有尝试进行任何动态导入(就像 Van Gale 提到的问题中一样),而是实际上只是尝试导入提供程序包中的所有模块。如果是这样的话,__init__.py你会想要这样的声明:

__all__ = ["acme1", "acme2", "acme3", "acme4", "acme5", "acme6"]

然后导入您将使用的所有内容 from ... import *

from providers import *

然后不用在代码中显式使用包名,只需调用导入的类

acme1.get()
acme2.get()

如果提供程序包中有足够多的模块,以至于填充__all__列表成为问题,您可能需要考虑将它们分解成更小的包或以其他方式存储数据。我个人不想每次我想重用包时都必须处理动态导入 schennagins。

于 2009-04-21T02:06:01.950 回答
3

今天问的这个问题,Python 模块的动态加载,应该会有你的答案。

于 2009-04-20T22:28:51.487 回答