tho*_*len 15 python python-import python-3.x
当包变得很大时,可能很难记住东西在哪里,并且我们想要的对象的点路径可能很麻烦。作者似乎解决这个问题的一种方法是将“最好的”对象的引用带到顶部,尽管这些代码实际上可以存在于下面的几个包级别中。
这让人可以说:
from pandas import wide_to_long
Run Code Online (Sandbox Code Playgroud)
代替
from pandas.core.reshape.melt import wide_to_long
Run Code Online (Sandbox Code Playgroud)
但是这样做的来龙去脉以及该方法的最佳实践是什么?不加载__init__.py带有许多导入的顶部(为了使它们在顶层可用)是否意味着包的单个对象的任何导入突然会占用比所需更多的内存 - 因为 中提到的所有内容都会自动__init__.py加载?
然而,包却可以做到这一点。例如,看看可以从顶层numpy或底层导入什么(可以在这个要点pandas中找到运行您自己的诊断的代码)。
$ python print_top_level_diagnosis.py numpy
--------- numpy ---------
599 objects can be imported from top level numpy:
19 modules
300 functions
104 types
depth count
0 162
1 406
2 2
3 29
4 1
$ python print_top_level_diagnosis.py pandas
--------- pandas ---------
115 objects can be imported from top level pandas:
12 modules
55 functions
40 types
depth count
0 12
3 37
4 65
5 1
Run Code Online (Sandbox Code Playgroud)
所有的方法都有优点和缺点,__init__.py你几乎可以做你想做的事。话虽如此,一个重要的指导原则是__init__.py永远不应该有任何“副作用”。这意味着它除了声明命名空间之外不应该执行任何其他操作。副作用确实会让库的用户感到困惑,甚至成为安全风险。
__init__.py名为“mylibrary”的模块中的示例:
import requests
result = requests.get("URL TO SOME VIRUS")
...
Run Code Online (Sandbox Code Playgroud)
在此示例中,运行import mylibrary实际上会下载某些内容(或发送信息)。
如果您__init__.py没有任何副作用,则有一些注意事项。首先是加载时间。每次导入库时,Python 都会遍历并运行(!)__init__.py它能找到的所有文件。这意味着,如果您的文件包含缓慢的操作,例如加载大文件或大量外部依赖项,则您的库的加载实际上可能会变得非常慢。您可以通过将昂贵的调用包装在函数中并公开该函数来解决此问题,但这仍然是需要考虑的问题。
另一件需要考虑的事情是库的版本控制。如果将文件移动到其他文件夹,您的所有用户或您自己是否需要更新所有导入语句?如果您查看该pandas库,您会发现它们创建了包含所有公共函数/类/等的api子模块(例如)。pandas.core.api所有导入都是从api子模块完成的,这确保了更改后,只有 1 个位置需要更新导入语句,并且一切都将继续工作。
| 归档时间: |
|
| 查看次数: |
3434 次 |
| 最近记录: |