【发布时间】:2013-02-08 00:08:36
【问题描述】:
我有一个 plypython 函数,它可以做一些 json 魔术。为此,它显然导入了 json 库。
每次调用函数时都会调用导入吗?有什么我必须注意的性能影响吗?
【问题讨论】:
标签: python json postgresql postgresql-9.1 plpython
我有一个 plypython 函数,它可以做一些 json 魔术。为此,它显然导入了 json 库。
每次调用函数时都会调用导入吗?有什么我必须注意的性能影响吗?
【问题讨论】:
标签: python json postgresql postgresql-9.1 plpython
PL/Python 函数体中的声明最终会变成一个普通的 Python 函数,因此会表现得如此。当 Python 函数第一次导入模块时,模块会缓存在 sys.modules 字典 (https://docs.python.org/3/reference/import.html#the-module-cache) 中。同一模块的后续导入将简单地将导入名称绑定到字典中找到的模块对象。从某种意义上说,我所说的可能会让人怀疑接受的答案中给出的提示的有用性,因为它有点多余,因为 Python 已经为你做了类似的缓存。
总而言之,我想说的是,如果您以简单使用 import 或 from [...] import 构造的标准方式导入,那么您不必担心在函数或其他方式中重复导入,Python 已经你覆盖了。
另一方面,Python 允许您绕过其原生导入语义并实现自己的(使用__import__() 函数和importlib 模块)。如果您正在这样做,也许您应该查看工具箱中的可用内容 (https://docs.python.org/3/reference/import.html)。
【讨论】:
import 在每个函数调用上执行。如果您在函数体中编写带有 import 语句的普通 Python 模块,与在模块级别相反,这与您将得到的行为相同。
是的,这会影响性能。
您可以通过像这样缓存导入来解决此问题:
CREATE FUNCTION test() RETURNS text
LANGUAGE plpythonu
AS $$
if 'json' in SD:
json = SD['json']
else:
import json
SD['json'] = json
return json.dumps(...)
$$;
这当然不是很漂亮,并且正在讨论更好的方法来做到这一点,但它们不会在 PostgreSQL 9.4 之前发生。
【讨论】: