在 Python 中,当您在函数内部导入时会发生什么?

发布于 2024-09-07 07:00:57 字数 97 浏览 4 评论 0 原文

在速度和内存效率方面,在函数内部导入 Python 模块和/或函数有哪些优缺点?

每次运行函数时它都会重新导入吗?或者无论函数是否运行,它都会在开始时重新导入一次?

What are the pros and cons of importing a Python module and/or function inside of a function, with respect to efficiency of speed and of memory?

Does it re-import every time the function is run, or perhaps just once at the beginning whether or not the function is run?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

生生不灭 2024-09-14 07:00:57

每次运行函数时都会重新导入吗?

不;或者更确切地说,Python 模块在每次导入时本质上都会被缓存,因此第二次(或第三次、第四次……)导入实际上并不强制它们再次经历整个导入过程。 1

无论函数是否运行,都会在开始时导入一次吗?

不,只有在执行该函数时才会导入它。 2, 3

至于好处:我想这取决于情况。如果您可能很少运行某个函数,并且不需要在其他任何地方导入该模块,那么仅在该函数中导入它可能会更有利。或者,如果存在名称冲突或其他原因,您不希望模块或模块中的符号随处可用,您可能只想将其导入到特定函数中。 (当然,对于这些情况,总是有 from my_module import my_function as f 。)

在一般实践中,它可能没有那么有益。事实上,大多数 Python 风格指南鼓励程序员将所有导入放在模块文件的开头。

Does it re-import every time the function is run?

No; or rather, Python modules are essentially cached every time they are imported, so importing a second (or third, or fourth...) time doesn't actually force them to go through the whole import process again. 1

Does it import once at the beginning whether or not the function is run?

No, it is only imported if and when the function is executed. 2, 3

As for the benefits: it depends, I guess. If you may only run a function very rarely and don't need the module imported anywhere else, it may be beneficial to only import it in that function. Or if there is a name clash or other reason you don't want the module or symbols from the module available everywhere, you may only want to import it in a specific function. (Of course, there's always from my_module import my_function as f for those cases.)

In general practice, it's probably not that beneficial. In fact, most Python style guides encourage programmers to place all imports at the beginning of the module file.

家住魔仙堡 2024-09-14 07:00:57

第一次从任何地方(函数内部或外部)导入 goo 时,goo.py(或其他可导入的形式)会被加载,并且 sys.modules[ 'goo'] 设置为由此构建的模块对象。任何未来在程序的同一运行中的导入(同样,无论是在函数内部还是外部)只需查找 sys.modules['goo'] 并将其绑定到裸名 goo 在适当的范围内。字典查找和名称绑定是非常快的操作。

假设第一个 import 无论如何都在程序的运行中完全摊销,“适当的范围”是模块级意味着每次使用 goo.this, goo .that 等是两个字典查找 - 一个用于 goo,另一个用于属性名称。将其设置为“函数级别”会为每次运行函数支付一个额外的局部变量设置(甚至比字典查找部分更快!),但会为每个 < 保存一次字典查找(将其替换为局部变量查找,速度非常快) code>goo.this (等)访问,基本上将此类查找所需的时间减半。

我们谈论的只是几纳秒,因此这几乎不是什么值得优化的事情。在函数中使用 import 的一个潜在的实质性优势是,在程序的给定运行中可能根本不需要该函数,例如,该函数处理错误、异常和罕见情况。一般情况;如果是这种情况,任何不需要该功能的运行甚至都不会执行导入(这节省了微秒,而不仅仅是纳秒),只有确实需要该功能的运行才会支付(适度但可衡量的)价格。

这仍然是一种只有在相当极端的情况下才值得的优化,在尝试以这种方式挤出微秒之前,我会考虑许多其他优化。

The very first time you import goo from anywhere (inside or outside a function), goo.py (or other importable form) is loaded and sys.modules['goo'] is set to the module object thus built. Any future import within the same run of the program (again, whether inside or outside a function) just look up sys.modules['goo'] and bind it to barename goo in the appropriate scope. The dict lookup and name binding are very fast operations.

Assuming the very first import gets totally amortized over the program's run anyway, having the "appropriate scope" be module-level means each use of goo.this, goo.that, etc, is two dict lookups -- one for goo and one for the attribute name. Having it be "function level" pays one extra local-variable setting per run of the function (even faster than the dictionary lookup part!) but saves one dict lookup (exchanging it for a local-variable lookup, blazingly fast) for each goo.this (etc) access, basically halving the time such lookups take.

We're talking about a few nanoseconds one way or another, so it's hardly a worthwhile optimization. The one potentially substantial advantage of having the import within a function is when that function may well not be needed at all in a given run of the program, e.g., that function deals with errors, anomalies, and rare situations in general; if that's the case, any run that does not need the functionality will not even perform the import (and that's a saving of microseconds, not just nanoseconds), only runs that do need the functionality will pay the (modest but measurable) price.

It's still an optimization that's only worthwhile in pretty extreme situations, and there are many others I would consider before trying to squeeze out microseconds in this way.

夜还是长夜 2024-09-14 07:00:57

当函数第一次执行时它会导入一次。

优点:

  • 与它们所使用的功能相关的导入可以
  • 轻松地在包中移动功能

缺点:

  • 无法看到该模块可能依赖于哪些模块

It imports once when the function executes first time.

Pros:

  • imports related to the function they're used in
  • easy to move functions around the package

Cons:

  • couldn't see what modules this module might depend on
誰ツ都不明白 2024-09-14 07:00:57

我是否可以建议一般性地不要问“X 会提高我的表现吗?”您使用分析来确定您的程序实际在哪里花费了时间,然后根据您将在哪里获得最大收益来应用优化?

然后您可以使用分析来确保您的优化也确实使您受益。

Might I suggest in general that instead of asking, "Will X improve my performance?" you use profiling to determine where your program is actually spending its time and then apply optimizations according to where you'll get the most benefit?

And then you can use profiling to assure that your optimizations have actually benefited you, too.

素手挽清风 2024-09-14 07:00:57

在函数内部导入将有效地导入模块一次......函数第一次运行时。

无论您是在顶部导入还是在函数运行时导入,它的导入速度都应该一样快。这通常不是导入 def 的好理由。优点?如果不调用该函数,则不会导入它。如果您的模块仅要求用户在使用您的特定功能时安装某个模块,这实际上是一个合理的原因...

如果这不是他的原因正在这样做,这几乎肯定是一个令人讨厌的主意。

Importing inside a function will effectively import the module once.. the first time the function is run.

It ought to import just as fast whether you import it at the top, or when the function is run. This isn't generally a good reason to import in a def. Pros? It won't be imported if the function isn't called.. This is actually a reasonable reason if your module only requires the user to have a certain module installed if they use specific functions of yours...

If that's not he reason you're doing this, it's almost certainly a yucky idea.

若相惜即相离 2024-09-14 07:00:57

当第一次调用该函数时,它会导入一次。

我可以想象如果我在导入的模块中有一个函数很少使用并且是唯一需要导入的函数,我可以想象这样做。虽然看起来相当牵强……

It imports once when the function is called for the first time.

I could imagine doing it this way if I had a function in an imported module that is used very seldomly and is the only one requiring the import. Looks rather far-fetched, though...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文