plpython中的导入语句如何处理?

17 投票
2 回答
4776 浏览
提问于 2025-04-17 16:45

我有一个用plypython写的函数,它能处理一些json相关的操作。为了做到这一点,它显然需要引入json这个库。

每次调用这个函数的时候,都会重新引入这个库吗?这样做会不会影响性能,有什么需要注意的地方吗?

2 个回答

5

在PL/Python函数的主体中声明的内容,最终会变成一个普通的Python函数,因此它会像普通的Python函数那样工作。当一个Python函数第一次导入一个模块时,这个模块会被存储在一个叫做sys.modules的字典里(https://docs.python.org/3/reference/import.html#the-module-cache)。之后再导入同一个模块时,Python会直接把导入的名字和字典中找到的模块对象关联起来。从某种意义上说,我的意思是,这可能会让人对接受的答案中给出的建议的实用性产生一些怀疑,因为Python已经为你做了类似的缓存,这样的建议就显得有些多余了。

总的来说,我想说的是,如果你按照标准方式使用importfrom [...] import来导入模块,那么你不需要担心重复导入的问题,无论是在函数中还是其他地方,Python都会为你处理好这些。

另一方面,Python也允许你绕过它的原生导入机制,自己实现导入功能(使用__import__()函数和importlib模块)。如果你正在这样做,也许你应该看看工具箱里有什么可用的工具(https://docs.python.org/3/reference/import.html)。

20

import 语句在每次调用函数时都会被执行。这就像你在一个普通的 Python 模块里,把 import 放在函数内部,而不是模块的最上面。

是的,这样做会影响性能。

你可以通过缓存你的导入来解决这个问题,像这样:

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 之前是不会实现的。

撰写回答