Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从文件导入特定类而不是从完整文件导入是否重要?_Python_Import - Fatal编程技术网

Python 从文件导入特定类而不是从完整文件导入是否重要?

Python 从文件导入特定类而不是从完整文件导入是否重要?,python,import,Python,Import,大多数关于Django或Flask的教程和书籍都从文件中导入特定类,而不是导入整个文件。 例如,从wrtforms.validators导入datarequired验证程序是通过从wtforms导入验证程序来完成的,而不是通过导入wtforms.validators作为valids导入,然后使用valids.datarequired访问datarequired 我的问题是:这有什么原因吗? 我想避免为计算/内存优化加载整个模块(这真的相关吗?)?还是仅仅为了使代码更具可读性?这取决于教程中可

大多数关于Django或Flask的教程和书籍都从文件中导入特定类,而不是导入整个文件。
例如,从
wrtforms.validators
导入
datarequired
验证程序是通过
从wtforms导入验证程序来完成的,而不是通过
导入wtforms.validators作为valids
导入,然后使用
valids.datarequired
访问
datarequired


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


我想避免为计算/内存优化加载整个模块(这真的相关吗?)?还是仅仅为了使代码更具可读性?

这取决于教程中可能是为了可读性而做的

通常,如果使用文件中的大多数类,则导入文件。如果文件包含许多类,但您只需要几个,只需导入这些类即可。 这是一个可读性和优化的问题

我的问题是:这有什么原因吗

from module_或_package import something
是典型的pythonic习惯用法(当然,当您只想在当前名称空间中导入
something
时)

另外,
导入模块或包。只有当
模块或包
是一个包而
某事物
是一个子模块时,它才会引发一个
导入错误(没有模块命名)
如果
某事物
是一个函数、类或
模块或包
中定义的任何对象,从stdlib中可以看出,
os.path
(它是
os.package
的子模块)与
datetime.date
(它是在
datetime
模块中定义的类):

只是语法上的糖分

import module_or_package
something = module_or_package.something
del module_or_package
import module
obj = module.obj
del module
编辑:你在评论中提到


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

因此,我似乎没有明确说明这一点:在Python中,您不能“仅导入子模块/类”

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

from module import obj
只是语法上的糖分

import module_or_package
something = module_or_package.something
del module_or_package
import module
obj = module.obj
del module
但是(除非你做了一些愚蠢的事情,比如在你的模块中定义一个TB级的大目录或列表),这实际上并不需要那么多时间,也不会消耗太多内存,而且一个模块在第一次导入时每个进程只有效执行一次,然后它被缓存在
sys.modules
中,所以后续的导入只会从缓存中获取它

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


wrt/packages and submodules,导入子模块还将执行包的
\uuuu init\uuuu.py
,并从中构建
模块
实例(在运行时,包也是
模块
)。包初始值设定项通常很短,实际上经常是空的FWIW…

@VaibhavVishal我完全同意star导入是不好的,但我不明白这与问题有什么关系…对,但导入整个模块意味着将其加载到内存中,这可能是只导入子模块/类的原因。@Alakazam如前所述,“从模块导入给定名称需要导入整个模块”-cf我编辑的答案了解更多详细信息…我理解,但您正在删除模块后面的其余部分。加载大量模块可能会带来内存问题(即使我认为加载模块不会导致内存过大,理论上它可以)。@Alakasam我不是在“删除模块的其余部分”-
del
语句只会删除名称(变量)和对象之间的绑定,它本身不会“删除”(以前)绑定的对象。仅当对象的refcount为null时,才会收集该对象,并且由于导入的模块缓存在
sys.modules
中,因此该语句之后refcount将保持正值。您可能想阅读关于python中的名称和绑定的内容:感谢您的解释,如果
del
只删除了绑定,那么请确保没有理由只导入一个类。我在很多django和flask项目中都看到了这一点,我只是觉得不可读,所以我想确定一下,通常你只想导入你需要的,以避免出现问题。但是,如果你从一个模块导入10个类中的9个,它会变得有点难看和不可读:我的问题是:会发生什么问题?覆盖类名称空间。假设您正在从两个不同的Views.py文件导入许多视图:您希望在第一次导入时使用“ExampleView”,但在第二次导入时,您还有一个“ExampleView”,它以不同的方式工作(但您不知道,因为您是盲目导入所有内容)。会发生的情况是,第二次导入“ExampleView”会覆盖第一次导入,您可能会损失很多时间,然后才能弄清楚为什么它不能按预期工作。当你在一个团队中处理相同的文件时,这一点尤其正确。你基本上说的是相反的。。当您从模块导入特定类时,可能会出现这些问题,我认为
import module
obj = module.obj
del module