围绕Python进口的方式?

Way around Python imports within imports?

对不起,如果这是一个非常新手的问题,我只是想知道一件事。

当在python中,代码被分成多个文件时,如何避免在同一个文件上进行大量的导入?

假设我有两个文件。主要内容。

主营:

1
2
3
4
import pygame
from pygame.locals import *
pygame.display.init()
blah

内容:

1
2
3
4
import pygame
from pygame.locals import *
pygame.display.init()
load content and stuff

pygame导入两次,display.init调用两次。这在其他地方是有问题的。有没有办法解决这个问题,还是只需要导入和导入?

我能想到的一种情况是:每次导入文件时,脚本都会写入该文件。这样,如果它被导入3次,它将运行3次,因此写入文件3次。

事先谢谢!


你误解了import的做法。它与include不同。加载的模块是单件的,其相应的文件不会被评估两次。

也就是说,构造良好的模块不会对导入产生副作用。这就是if __name__=='__main__'习语的目的。

不要试图"清理"进口商品。从文件中导入需要使用的所有内容。您可以减少对import *的使用,但这纯粹是为了代码的可读性和可维护性。


您应该避免在导入时发生任何事情(请参阅下文)。python文件首先是一个模块,因此它可以也应该被其他python模块使用。如果在python文件的导入阶段发生了"事件",那么当另一个模块导入该文件时,可能会以不希望的方式发生这种情况。

每个模块应该只定义要使用的东西:类、函数、常量,并等待其他东西使用它们。

显然,如果导入时没有脚本,那么就不可能真正使用任何脚本并使其"发生"。对于直接调用模块的异常情况,有一个特殊的成语。每个python文件都有一个变量,__name__是用导入时的模块名自动创建的。当您从命令行运行一个脚本(或者不管您启动了什么脚本)时,它没有被导入,也没有名称可供它使用,因此__name__变量将具有一个特殊值"__main__",表明它是正在执行的脚本。您可以检查此情况并采取相应措施:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# main.py
import pygame
from pygame.locals import *

import content

def init():
    pygame.display.init()

def stuff():
    content.morestuff()

if __name__ == '__main__':
    init()
    stuff()
1
2
3
4
5
6
7
8
9
10
11
12
13
# content.py
import pygame
from pygame.locals import *

def init():
    pygame.display.init()

def morestuff():
   "do some more stuff"

if __name__ == '__main__':
    init()
    morestuff()

这样,init()pygame.display.init()只被用户运行的脚本调用过一次。假定已调用init()而运行的代码被分解成另一个函数,并根据主脚本的需要调用(无论发生什么情况)。


import语句应该是声明您正在使用另一个模块中的某些内容。它们不应该被用来导致某些事情发生(比如写入文件)。正如FrancisAvila所指出的,python无论如何都不会尝试多次执行模块的代码。

因此,给定的import语句是否会导致任何事情发生,是应用程序在运行时的全局属性;您不能仅仅从导入语句和模块的源代码中分辨出来,因为这取决于项目中其他任何代码是否已经导入了该模块。

因此,在执行时让模块"做些什么"通常是实现应用程序的一种非常脆弱的方法。但是"做些什么"并没有硬性和快速的定义,因为很明显,模块需要创建其他模块将从中导入的所有东西,这些东西可能涉及读取配置文件,甚至可能写入日志文件,或任何其他东西。但是,任何看起来像程序的"操作"的事情,而不仅仅是从模块中导入的"设置"事情,通常都不应该在模块范围内完成。