从Python文件中暴露/导出类而不是模块

28

我正在学习Python以及如何组织代码。

考虑以下项目结构

<project root>/controllers/user_controller.py

这个文件包含了

class UserController:
  def index():
    # Something

当从外部导入时,它最终变成

import controllers.user_controller

controller_instance = controllers.user_controller.UserController()
作为Ruby开发人员,如果控制器文件夹在加载路径中(例如Rails),controllers.UserController()或者只有UserController()更加自然。有没有一种可以省略包名称的(干净)方法?我知道我可以使用from controllers.user_controller import UserController,但是我并不喜欢冗长。我希望每个类都有一个Python文件,但我不想为每个类创建一个新模块。

你对 import controllers.user_controller as ctrl 有异议吗? - pstatix
1
是的,我认为ctrl.UserController()不太好理解。 - Niels B.
2个回答

46

一种方法是将模块导入到父模块中。换句话说,假设您有以下目录结构:

mycoolmodule/
mycoolmodule/__init__.py
mycoolmodule/coolclass.py
mycoolmodule/coolutil.py

文件coolclass.py的代码:

class CoolClass:
    ...

coolutil.py的代码:

class CoolUtil:
    ...

代码用于init.py

from coolclass import CoolClass
from coolutil import CoolUtil

既然您已经在软件包级别上将它们提供,那么现在可以直接从那里导入它们。例如,以下代码将有效:

from mycoolmodule import CoolClass

2
在我的 __init__.py 文件中,出现了 ModuleNotFoundError: No module named 'coolclass' 的错误提示,尽管我认为我已经做得没问题了。 - Seangle
很难在没有看到你的具体操作的情况下说,但是上面的例子应该可以工作。 - Ryan Widmaier
3
我认为 _init_.py 应该包含 .coolclass 而不是 coolclass,并且应包含 .coolutil 而不是 coolutil。否则会因为循环依赖而无法正常工作。 - I.R.

7
也许你应该依赖于相对路径,就像这样链接描述所示,但是:

init.py的代码:

from .coolclass import CoolClass
from .coolutil import CoolUtil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接