如何构造面向对象的Python3项目及其导入?
我有一个面向对象的Python 3.7项目,其结构如下:如何构造面向对象的Python3项目及其导入?,python,python-3.x,Python,Python 3.x,我有一个面向对象的Python 3.7项目,其结构如下: ├── 插件 │ ├── 图书管理 │ │ ├── book_inserter.py │ │ ├── book_remover.py │ │ ├── __初始值 │ │ ├── book.py │ │ ├── book_sampler.py │ │ ├── 操作员 │ │ │ ├── __初始值 │ │ │ ├── register_book.py │ │
├── 插件
│ ├── 图书管理
│ │ ├── book_inserter.py
│ │ ├── book_remover.py
│ │ ├── __初始值
│ │ ├── book.py
│ │ ├── book_sampler.py
│ │ ├── 操作员
│ │ │ ├── __初始值
│ │ │ ├── register_book.py
│ │ │ ├── 注销\u book.py
│ │ │ └── 将书标记为失踪.py
│ ├── __初始值
│ ├── 读者管理
│ │ ├── __初始值
│ │ ├── reader.py
│ │ ├── reader_creator.py
│ │ ├── reader\u emailer.py
│ │ ├── reader_remover.py
│ │ ├── 操作员
│ │ │ ├── __初始值
│ │ │ ├── 创建_reader.py
│ │ │ ├── 删除_reader.py
│ │ │ └── email_reader.py
├── 测验
│ ├── __初始值
│ ├── 图书管理考试
│ │ ├── __初始值
│ │ ├── test_book.py
│ │ ├── test\u book\u inserter.py
│ │ ├── test_book_remover.py
│ │ ├── test_book_sampler.py
│ │ ├── test_mark_book_as_missing_operator.py
│ │ ├── test\u register\u book\u operator.py
│ │ ├── test_unregister_book_operator.py
│ ├── 读者管理测试
│ │ ├── __初始值
│ │ ├── test_reader.py
│ │ ├── test\u reader\u creator.py
在像test\u mark\u book\u as\u missing\u操作符这样的测试中
I最终得到如下导入:
来自plugins.book\u management.book\u inserter导入BookInserter
从plugins.book\u management.operators.mark\u book\u as\u缺少导入(
MarkBookAsMissingOperator
)
从plugins.reader\u management.reader\u creator导入ReaderCreator
从plugins.reader\u management.operators.create\u reader import(
CreateReaderOperator
)
这感觉真的很糟糕,有这些非常详细的部分导入。所以我猜我一定是做错了。理想情况下,导入plugins.reader\u management
和plugins.reader\u management.operators
,可能更短一些的东西看起来更可读
book\u inserter.py
正在定义一个类bookinerter
。理想情况下,我希望保持这种1类/1文件结构。很明显,这会导致文件数量的膨胀,但也允许使用更短、更集中的文件。但是,如果这是非常非Pythonic的,我愿意听到为什么以及如何调整代码结构
最后,我一直在使用这种多层体系结构(plugins/*\u management/operators/*.py
),但这会导致很长的导入行,因此我经常遇到合法的lint问题
我一直在考虑从顶级模块导入子模块(如book_management,在book_management/\uuuu init_uuuuuuuuuuuuupy
中),但我不确定这是否是一种好的做法,而且这似乎违反了文件中不包含未使用导入的原则。(我也会因此面临循环进口的风险吗?)
简言之,我的主要问题是:构造这样一个项目并设置导入的(Pythonic)方法是什么(理想情况下,有一些理由说明为什么这是Pythonic方法)。使用\u init\u.py
压缩名称空间。使用\uuuuuuuuuuuuuuuuuuuuuuuuu
可以清楚地定义导入的名称是用于导出的
# plugins/book_management/__init__.py
from .book_inserter import BookInserter
from .operators.mark_book_as_missing import MarkBookAsMissingOperator
# more imports
__all__ = [
'BookInserter',
'MarkBookAsMissingOperator',
# more exports
]
这减少了使用时导入的长度和数量:
# test_mark_book_as_missing_operator
from plugins.book_management import BookInserter, MarkBookAsMissingOperator
from plugins.reader_management import ReaderCreator, CreateReaderOperator
对于每个文件1个定义是否是件坏事,似乎还没有达成共识。但是,对于标准库和许多第三方模块,通常会将所有直接相关的类和函数放在一起。有没有办法通过绝对导入或循环导入来实现这一点?@sunless您的意思是从plugins.book\u inserter import bookinerter中导入?相对导入与绝对导入具有完全相同的行为,它们只是避免重复和硬编码包名。