导入和execfile之间的区别 [英] Difference between import and execfile

查看:121
本文介绍了导入和execfile之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个文件utils.py,其中包含一个名为f1()的函数.

I have a file utils.py containing a function called f1().

从另一个Python脚本中,我可以import utilsexecfile('utils.py')并可以访问f1().两种方法有什么区别?

From another Python script I can import utils or execfile('utils.py') and have access to f1(). What are the differences between the two methods?

推荐答案

有很多区别,但是从您的角度来看,最重要的是import可以让您更好地控制在其中定义对象的名称空间utils.py结束.

There are many differences, but from your point of view the most significant is probably that import gives you more control over the namespace in which the objects defined in utils.py end up.

让我们考虑import上的三个变体.第一个是您问过的:

Let's consider three variants on import. The first is the one you asked about:

import utils
utils.f1()

utils是唯一添加到您的工作空间中的符号-基本工作空间中任何先前存在的f1都不会被覆盖,并且如果没有,则f1()本身不会被覆盖被认可.对于我打算维护的代码,我非常喜欢这种导入方式,因为它使我可以轻松地在源文件中搜索依赖于utils的所有位置.

utils is the only symbol that has been added to your workspace—any pre-existing f1 in your base workspace will not have been overwritten, and if there is none, then f1() on its own will not be recognized. For code I intend to maintain, I greatly prefer this way of importing, because it makes it easy for me to search my source file for all the places in which it depends on utils.

但是如果每次都说utils.f1()太冗长,那么您可以这样做:

But if saying utils.f1() every time is too verbose then you can do this:

from utils import f1
f1()

现在,如果您说将调用utils.f1()f1(),因为这是您现在与工作空间中的名称f1关联的代码对象.现在,要稍微了解一下您的代码在utils模块上所处的位置,就比较困难.但是,至少这种类型的import语句可让您精确控制导入的符号和不导入的符号.您甚至可以在此过程中重命名符号:

Now if you say f1() that will call utils.f1(), because that is the code object that you have now associated with the name f1 in your workspace. It's now slightly harder to get an overview of where your code is reliant on the utils module. But at least this type of import statement gives you precise control over which symbols were imported and which not. You can even rename symbols during this process:

from utils import f1 as EffOne
EffOne()  

最后,您可以选择完全失去对名称空间的控制:

Finally you can choose to lose control over the namespace entirely:

from utils import *

现在,谁知道要导入什么符号:基本上utils必须提供的所有内容(或者,如果utils开发人员麻烦地指定了__all__属性,则列出的所有内容).我建议您仅将import *用于快速和肮脏的编程.

Now, who knows what symbols have been imported: basically everything that utils has to offer the world (or, if the utils developer took the trouble to specify an __all__ attribute, then everything listed there). I'd advise you to use import * only for quick-and-dirty programming, if at all.

这实际上是从命名空间角度最接近execfile的导入样式:execfile('utils.py')的作用与from utils import *相同,因为它会将utils所定义的所有符号转储到您的计算机中.工作区.略有不同是,execfile甚至不会将自己限制为__all__中的符号-实际上,__all__符号本身只会与其他所有内容一起丢在您的腿上.

This is actually the importing style that is closest to execfile from the namespace point of view: execfile('utils.py') does much the same as from utils import * in that it dumps all symbols defined by utils willy-nilly into your workspace. One slight difference is that execfile won't even limit itself to the symbols in __all__ if that is defined—in fact, the __all__ symbol itself will just get dumped in your lap along with everything else.

除名称空间外,from utils import *execfile('utils.py')之间仍然存在许多差异.一个正在缓存:对utils的第二次import调用将非常快(该代码将不会重新运行),但是对execfile('utils.py')的第二次调用可能与第一次调用一样长,因为代码重新运行.另外,在utils.py中可能有一些代码(通常是测试代码),utils作者不希望在导入时运行,而当通过execfile执行文件时,该代码仅为 .此类代码放在if __name__ == '__main__':子句中.

Beyond namespaces, there are still plenty of differences between from utils import * and execfile('utils.py'). One is caching: a second import call on utils will be very fast (the code will not be re-run), but a second call to execfile('utils.py') may take just as long as the first because the code will be re-run. Also, there may be some code (often test code) inside utils.py that the utils author does not want to run at import time, but only when the file is executed via execfile. Such code is placed inside an if __name__ == '__main__': clause.

这篇关于导入和execfile之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆