关于如何导入和组织我的子模块,我有点迷茫,我需要一些文献和一些约定.
问题
我们想编写一个用Python编写的新包,它由几个组件组成:
>对最终用户有用的类和函数
>很少使用类和函数
>包本身只需要实用程序类和函数
>外部模块
我们考虑这种架构:
pizzafactory
├── __init__.py
├── salt.py
├── water.py
├── vegetables
│ ├── __init__.py
│ └── tomatoes.py
└── dough
├── __init__.py
└── flour.py
一些考虑
>最终用户不需要使用面团或水等原料
>客户只需要在pizzafactory / __ init__.py中描述的比萨饼
>面团工厂需要盐和水
>顾客可能想在披萨上添加一些西红柿.
文件pizzafactory / __ init__.py几乎需要所有模块,但因为我们不希望用无用的东西污染最终用户命名空间.除了客户可能使用的那些之外,我建议安静地进口配料:
# pizzafactory/__init__.py
import salt as _salt
import dough as _dough
import vegetables.tomatoes
import oven as _oven # External package
面团工厂需要一些水,但需要使用该子模块(制作面包)的用户可能不想看到水.
# pizzafactory/dough/__init__.py
import pizzafactory.water as _water
讨论
首先,我觉得直接导入完整包装的所有内容总是更容易:
import pizzafactory
def grab_tomato():
return pizzafactory.vegetables.tomatoes.BeefsteakTomato()
或只是必需的元素:
from pizzafactory.vegetables.tomatoes import BeefsteakTomato
def grab_tomato():
return BeefsteakTomato()
这两种方法都很常见,但它可能污染了pizzafactory命名空间,因此最好修改导入名称.我重新认识到没有人这样做,我不知道为什么.
题
在这个通用示例中,我想知道如何正确导入模块,子模块和外部包,以便:
>最小化命名空间占用空间
>帮助最终用户清楚地看到他打算使用的内容
最佳答案
Both of these methods are common, but it may pollute the pizzafactory namespace, so it may be preferable to mangle the import names. I relalized that nobody does that and I don’t know why.
Python是一种同意的成人语言,在大多数情况下,我们将门打开并且所有内容都是公开的.
如果你担心的只是拥挤命名空间,你应该定义__all__以及使用单引导下划线. – PEP8建议名称修改应该只用于避免命名冲突,所以这可能是为什么没有人这样做.
参见PEP8的Public and internal interfaces部分以及Naming Convensions.
PEP8是“适当”方式来做这些事情的指南.虽然,它不一定是法律指南.你可以灵活地做你认为适合你的包装的东西,这导致我最喜欢的PEP8 – A Foolish Consistency is the Hobgoblin of Little Minds部分
在没有与包中的代码充分密切的情况下,人们可能无法提供超出PEP8的关于如何完成的建议.如果你有时间,Raymond Hettinger的谈话Beyond PEP 8是值得一看的.