一尘不染

从子目录中的不同文件导入类

python

这是我正在使用的结构:

directory/
          script.py
          subdir/
                 __init__.py
                 myclass01.py
                 myclass02.py

我想要做的就是在script.py中定义的类进口myclass01.pymyclass02.py。如果我做:

from subdir.myclass01 import *

对于中定义的类,它工作正常myclass01.py。但是使用此解决方案时,如果在不同文件中定义了许多类,subdir并且我想导入所有这些类,则必须为每个文件键入一行。必须有一个捷径。我试过了:

from subdir.* import *

但这没有解决。

编辑 :这是文件的内容:

这是__init__.py__all__按照Apalala的建议使用):

__all__ = ['MyClass01','MyClass02']

这是myclass01.py

class MyClass01:
    def printsomething():
        print 'hey'

这是myclass02.py

class MyClass02:
    def printsomething():
        print 'sup'

这是script.py

from subdir import *
MyClass01().printsomething()
MyClass02().printsomething()

这是我尝试运行时得到的跟踪script.py

File "script.py", line 1, in <module>
    from subdir import *
AttributeError: 'module' object has no attribute 'MyClass01'

阅读 168

收藏
2020-12-20

共1个答案

一尘不染

尽管此处使用的名称与问题的目录结构中显示的名称不同,但是您可以使用我对名为Namespacing和classes的问题的答案。在__init__.py这里所示本来还允许usepackage.py脚本已经这样写的(package映射到subdir你的问题,并Class1myclass01等):

from package import *

print Class1
print Class2
print Class3

修订(更新):

糟糕,抱歉,我的其他答案中的代码并未完全满足您的要求-
它只会自动导入任何程序包子模块的名称。为了使其也从每个子模块导入命名属性,需要多几行代码。这是软件包__init__.py文件的修改版本(在Python
3.4.1中也可以使用):

def _import_package_files():
    """ Dynamically import all the public attributes of the python modules in this
        file's directory (the package directory) and return a list of their names.
    """
    import os
    exports = []
    globals_, locals_ = globals(), locals()
    package_path = os.path.dirname(__file__)
    package_name = os.path.basename(package_path)

    for filename in os.listdir(package_path):
        modulename, ext = os.path.splitext(filename)
        if modulename[0] != '_' and ext in ('.py', '.pyw'):
            subpackage = '{}.{}'.format(package_name, modulename) # pkg relative
            module = __import__(subpackage, globals_, locals_, [modulename])
            modict = module.__dict__
            names = (modict['__all__'] if '__all__' in modict else
                     [name for name in modict if name[0] != '_'])  # all public
            exports.extend(names)
            globals_.update((name, modict[name]) for name in names)

    return exports

if __name__ != '__main__':
    __all__ = ['__all__'] + _import_package_files()  # '__all__' in __all__

或者,您可以将以上内容放入包目录中单独的.py模块文件中(例如),_import_package_files.py并从包中使用它,__init__.py如下所示:

if __name__ != '__main__':
    from ._import_package_files import *  # defines __all__
    __all__.remove('__all__')  # prevent export (optional)

无论您以什么名字命名文件,它都应该以_下划线字符开头,这样它就不会import递归地尝试自身。

2020-12-20