简体   繁体   English

围绕Python进口的方式?

[英]Way around Python imports within imports?

Sorry if this is a very novice question, I was just wondering one thing. 对不起,如果这是一个非常新手的问题,我只是想知道一件事。

When in python and your code is split up amongst multiple files, how would you avoid a ton of imports on the same thing? 在python中,你的代码被分成多个文件,你怎么能避免在同一个东西上进行大量的导入?

Say I have 2 files. 说我有2个文件。 Main, and Content. 主要和内容。

Main: 主要:

import pygame
from pygame.locals import *
pygame.display.init()
blah

Content: 内容:

import pygame
from pygame.locals import *
pygame.display.init()
load content and stuff

pygame is imported twice and display.init is called twice. pygame导入两次, display.init被调用两次。 This is problematic in other places. 这在其他地方是有问题的。 Is there anyway to get around this, or must it just import and import and import? 反正有没有解决这个问题,还是只需要导入导入导入?

One situation I can think of is this: A script that writes to a file everytime it is imported. 我能想到的一种情况是:每次导入时都会写入文件的脚本。 That way, if it's imported 3 times, it gets run 3 times, therefore writing to the file 3 times. 这样,如果它被导入3次,它会运行3次,因此写入文件3次。

Thanks in advance! 提前致谢!

You misunderstand what import does. 你误解了import作用。 It's not the same as include . 它与include Loaded modules are singletons and their corresponding files are not evaluated twice. 加载的模块是单例,其相应的文件不会被评估两次。

That said, a well-constructed module will not have side-effects on import. 也就是说,构造良好的模块不会对导入产生副作用。 That's the purpose of the if __name__=='__main__' idiom. 这就是if __name__=='__main__'成语的目的。

Do not attempt to "clean up" your imports. 不要试图“清理”您的进口。 Import everything you need to use from within a file. 从文件中导入您需要使用的所有内容。 You could make less use of import * , but this is purely for code readability and maintainability. 您可以减少使用import * ,但这纯粹是为了代码可读性和可维护性。

You should avoid having anything happen at import(except, see further down). 您应该避免在导入时发生任何事情(除了,请参见下文)。 a python file is a module first, so it can and should be used by other python modules. python文件首先是一个模块,所以它可以并且应该被其他python模块使用。 If something "happens" in the import stage of a python file, then it may happen in an undesirable way when that file is imported by another module. 如果在python文件的导入阶段“发生”某些事情,那么当该文件由另一个模块导入时,它可能以不合需要的方式发生。

Each module should just define things to be used: classes, functions, constants, and just wait for something else to use them. 每个模块应该只定义要使用的东西:类,函数,常量,并等待其他东西使用它们。


Obviously, if no script ever does at import, then it's not possible for anything to actually get used and make stuff "happen". 显然,如果在导入时没有任何脚本,那么实际上不可能使用任何东西并让事情“发生”。 There is a special idiom for the unusual case that a module was called directly. 对于不直接调用模块的异常情况,有一种特殊的习惯用法。 Each python file has a variable, __name__ automatically created with the module name it was imported as. 每个python文件都有一个变量__name____name__自动创建了导入的模块名称。 When you run a script from the command line (or however you have started it), it wasn't imported, and there's no name for it to have, and so the __name__ variable will have a special value "__main__" that indicates that it's the script being executed. 当您从命令行运行脚本时(或者您已经启动它),它没有被导入,并且没有它的名称,因此__name__变量将具有一个特殊值"__main__" ,表明它是正在执行的脚本。 You can check for this condition and act accordingly: 您可以检查此情况并采取相应措施:

# main.py
import pygame
from pygame.locals import *

import content

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

def stuff():
    content.morestuff()

if __name__ == '__main__':
    init()
    stuff()
# content.py
import pygame
from pygame.locals import *

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

def morestuff():
    "do some more stuff"

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

This way; 这条路; init() and thus pygame.display.init() are only ever called once, by the script that was run by the user. init()pygame.display.init()只能由用户运行的脚本调用一次。 the code that runs assuming that init() has already been called is broken into another function, and called as needed by the main script (whatever that happens to be) 假设已经调用了init()而运行的代码被分解为另一个函数,并且根据需要被主脚本调用(无论发生什么)

import statements are supposed to be declarations that you're using something from another module. import语句应该是你正在使用来自另一个模块的东西的声明。 They shouldn't be used to cause something to happen (like writing to a file). 它们不应该用于导致某些事情发生(比如写入文件)。 As noted by Francis Avila, Python will try not to execute the code of a module more than once anyway. 正如Francis Avila所指出的,Python无论如何都会尝试不再执行模块的代码。

This has the consequence that whether a given import statement will cause anything to happen is a global property of the application at runtime; 这导致给定的import语句是否会导致任何事情发生,这是应用程序在运行时的全局属性; you can't tell just from the import statement and the source code of the module, because it depends on whether any other code anywhere else in the project has already imported that module. 你无法从import语句和模块的源代码中分辨出来,因为它取决于项目中其他地方的任何其他代码是否已导入该模块。

So having a module "do something" when executed is generally a very fragile way to implement your application. 因此,在执行模块时“执行某些操作”通常是实现应用程序的一种非常脆弱的方式。 There is no hard and fast definition of "do something" though, because obviously the module needs to create all the things that other modules will import from it, and that may involve reading config files, possibly even writing log files, or any number of other things. 但是,“做某事”没有硬性和快速的定义,因为很明显模块需要创建其他模块将从中导入的所有内容,这可能涉及读取配置文件,甚至可能包括编写日志文件或任何数量的其他事情。 But anything that seems like the "action" of your program, rather than just "setting up" things to be imported from the module, should usually not be done in module scope. 但是,任何看起来像程序“动作”的东西,而不仅仅是“设置”从模块导入的东西,通常不应该在模块范围内完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM