命名空间与类

7 投票
2 回答
5349 浏览
提问于 2025-04-16 12:31

我想在Python中写一些我认为比较易读的代码。我需要一个模块,里面包含多个类。理论上,我知道怎么做:我可以把类的定义放在一个模块文件里。

为了提高可读性,我想把每个类的定义放在单独的文件里(因为它们开始变得有点长了!),然后把这些类放在一个目录里。每当我创建一个新文件时,虽然我需要的内容在那儿可见,但里面的类定义却被不必要的模块限制住了。

我该怎么做呢?在“Python”中应该怎么做呢?

2 个回答

3

如果你想避免在很多地方硬编码模块路径、文件、类和函数名称,可以尝试下面的方法,这样可以动态导入它在一个包的子目录中找到的几乎所有Python文件。

关键在于记住,__init__.py 文件本身就是一个相对自由的Python脚本,因此可以进行比较复杂的处理,以确定包的命名空间中有什么内容。

文件 package\__init__.py:

def _import_package_files():
    """ Dynamically import all the Python modules in this module's sub directory. """
    import os
    import sys
    import traceback

    package_path = os.path.split(__file__)[0]
    package_directory = os.path.split(package_path)[1]

    for fn in os.listdir(package_directory):
        globals_, locals_ = globals(), locals()
        # process all python files in directory that don't start with underscore
        if fn[0] != '_' and fn.split('.')[-1] in ('py', 'pyw'):
            modulename = fn.split('.')[0] # filename without extension
            subpackage = ".".join([package_directory, modulename])
            try:
                module = __import__(subpackage, globals_, locals_, [modulename])
            except:
                traceback.print_exc(file=sys.stdout)
                raise # reraise exception

_import_package_files()

文件 package\Class1.py:

class Class1(object):
    pass

文件 package\Class2.py:

class Class2(object):
    pass

文件 package\Class3.py:

class Class3(object):
    pass

文件 usepackage.py:

import package

print(package.Class1)
print(package.Class2)
print(package.Class3)

运行 usepackage.py 的输出结果:

<module 'package.Class1' from 'C:\Files\package\Class1.pyc'>
<module 'package.Class2' from 'C:\Files\package\Class2.pyc'>
<module 'package.Class3' from 'C:\Files\package\Class3.pyc'>
8

__init__.py文件里把它们全部导入,然后让使用者导入这个包。

from .module1 import Class1
from .module2 import Class2
 ...

撰写回答