首页 > 解决方案 > 从文件而不是完整文件导入特定类是否重要?

问题描述

大多数关于 Django 或 Flask 的教程和书籍都从文件中导入特定的类,而不是导入整个文件。
例如,从通过导入验证器而不是通过DataRequiered导入验证器,然后使用. 我的问题是:这有原因吗? 我想避免加载整个模块以进行计算/内存优化(真的相关吗?)?还是只是为了使代码更具可读性?wrtforms.validatorsfrom wtforms import validatorsimport wtforms.validators as validsDataRequieredvalids.DataRequiered




标签: pythonimport

解决方案


我的问题是:这有原因吗?

from module_or_package import something是规范的 pythonic 习惯用法(当然,当您只想something在当前命名空间中导入时)。

此外,import module_or_package.something仅当module_or_package是一个包和一个子模块时才有效something,它引发一个ImportError(No module named something)ifsomething是一个函数、类或任何定义module_or_package在在模块中):os.pathos.packagedatetime.datedatetime

>>> import os.path as p
>>> p
<module 'posixpath' from '/home/bruno/.virtualenvs/blook/lib/python2.7/posixpath.pyc'>

对比

>>>import datetime.date as d
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named date

考虑避免加载整个模块以进行计算/内存优化(它真的相关吗?)

完全不相关 - 从模块导入给定名称需要导入整个模块。其实这个:

from module_or_package import something

只是语法糖

import module_or_package
something = module_or_package.something
del module_or_package

编辑:你在评论中提到

是的,但是导入整个模块意味着将其加载到内存中,这可能是只导入子模块/类的原因

所以看来我没能说清楚:在 Python 中,你不能“只导入一个子模块/类”,句号。

在 Python 中importclassdef都是可执行语句(实际上只是操作的语法糖,您可以“手动”使用函数和类进行操作)。导入模块实际上包括在模块的顶层执行所有代码(将实例化functionclass对象)并创建一个module对象(module类型的实例),其属性将是顶层定义的所有名称 via import,语句或defviaclass显式赋值。只有当所有这些都完成后,您才能访问模块中定义的任何名称,这就是为什么,如上所述,

from module import obj

只是语法糖

import module
obj = module.obj
del module

但是(除非你做了一些愚蠢的事情,比如在你的模块中定义一个 TB 级的字典或列表)这实际上并不会花费太多时间也不会吃太多内存,并且一个模块在第一次导入时每个进程只有效执行一次 -然后它被缓存,sys.modules因此后续导入仅从缓存中获取它。

此外,除非您主动阻止它,否则 Python 将缓存模块的已编译版本(.pyc 文件),并且仅在 .pyc 丢失或比源 .py 文件旧时才重新编译它。

wrt/ 包和子模块,导入子模块也将执行包__init__.py并从中构建一个module实例(IOW,在运行时,包也是一个module)。包初始化程序通常相当短,实际上经常为空 FWIW ...


推荐阅读