函数/模块的 import,是细到函数里去做,还是在文件里面做,有区别吗,哪种好?

2023-05-29 10:57:28 +08:00
 pppguest3962

如:

# testFunA.py
import re

afun():
strList = re.findall(xx)

bfun():
strList = re.findall(xx)

cfun():
strList = re.findall(xx)

OR

# testFunB.py
afun():
import re
strList = re.findall(xx)

bfun():
import re
strList = re.findall(xx)

cfun():
import re
strList = re.findall(xx)

.py 都是自写函数工具系列,被其它引用处理环节, re 是官库自带,相信重复 import 应该不会有坑,
如果是自写优化不好的函数呢,两种情况用起来会有怎么样的不同?

2516 次点击
所在节点    Python
18 条回复
ho121
2023-05-29 11:23:38 +08:00
重复 import 一般情况下没有问题。但 import 也会消耗 CPU ,所以
如果是使用频率较高的,建议放在函数外面,可以减少大量 import 带来的 CPU 消耗。
如果是使用频率较低的,建议放在函数里面,可以加快程序启动速度,一定程度减少内存使用。
lanlanye
2023-05-29 12:26:13 +08:00
一般建议放外面,除非你某个函数只调用一次,或者有什么不得不放在里面的理由
westoy
2023-05-29 12:27:41 +08:00
性能差距可以忽略不计, 无非是从全局变量里找还是从 sys.modules 里找

但是 PEP8 是建议放在顶部的
Trim21
2023-05-29 12:43:06 +08:00
第二种写法不累吗?
CLMan
2023-05-29 12:47:29 +08:00
按照编程的常识来:大多数语言都是放在文件的头部。

违背编程常识的 feature 发明,通常不是陷阱就是鸡肋,尽量避免使用。
AlohaV2
2023-05-29 13:04:59 +08:00
一般是放在文件头部。可以看下 pandas frame.py 的源码( https://github.com/pandas-dev/pandas/blob/main/pandas/core/frame.py),在函数体内的 import 一般是 form ... import...这样的,主要是为了函数体内方便,但又不影响整个文件
miaotaizi
2023-05-29 14:16:36 +08:00
一般情况我都写顶部.

但是, 当我遇到循环引用的时候就没辙了.... 只好在函数里面去 import
fbichijing
2023-05-29 14:55:58 +08:00
同意二楼的说法,特别是 "有什么不得不放在里面的理由"。

基本都写在外面,只有在很少数情况下某个功能用得很少但是需要导入一个新的库时,才放到函数内部。因为这个时候放在外面让我觉得亏。
NoOneNoBody
2023-05-29 15:14:41 +08:00
[afun() for _ in range(10000000)]

print(len(df)) # 1000000
df['newcol'] = df.col.apply(bfun)

函数内 import 目的可能是两个:
1. 是按需加载
2. 是避免 namespace 冲突(作用域),例如必须使用一个名为 re 的全局变量
一般是自己熟知被调用的状况,不能预估还是按约定俗成写吧
Trim21
2023-05-29 17:03:03 +08:00
性能差距其实还是有的,`re.findall('', '')`的情况下在函数内 import 就会慢个 15%左右。

除非是 cli 程序,第二种写法能减少 python 需要加载的模块数,否则想不出这么做的理由
kenvix
2023-05-29 20:49:53 +08:00
如果有分支,只有一个分支会用到 import 的模块,并且 import 的开销很大(比如 import torch ),就用第二种做法
kenvix
2023-05-29 20:51:35 +08:00
* 我刚才提到的分支是从程序的整个生命周期考虑的,如果整个生命周期一定会用到 import 的模块,那就也用第一种做法
NoDocCat
2023-05-29 23:07:06 +08:00
除非类似于 js import() 的动态导入, 或者利用宏做编译时选择, 否则的话按照常规放到头部.
weyou
2023-05-30 01:31:12 +08:00
不管是少数情况才用到的模块还是用的很多的模块都建议放在文件头部,有利于提早发现模块缺失错误
akaHenry
2023-05-30 08:05:33 +08:00
python 的 import 分 全局 import 和 局部 import, 是因为 局部 import, 是用来解决 模块之间 出现"循环引用(互相 import)".

这也是考察 python 基本功的一个常见面试题.

上面只有 1 位同学说到点子上.

正面回答:

1. 当出现循环引用冲突, 才需要使用 local import. 否则, 都没必要使用(注意是没必要, 要杠, 就你对).

2. 至于 import lib 多, 影响运行速度, 这种想法, 可以理解+嘲笑. 都在用 python 了, 还纠结这些. 典型没睡醒. (有这个功夫, 把代码性能优化好点吧...
rev1si0n
2023-05-30 10:04:43 +08:00
没见过你这种写法,当然也不是没有,有些需要看时机导入的包会这样写,正常没人这么做。
kenvix
2023-05-30 11:54:05 +08:00
@akaHenry 还搁这儿用绝对化语气呢😅我还真得和你杠,import torch 的开销你知道有多少吗?😅
XueXianqi
2023-05-30 17:18:13 +08:00
个人见解:

- 不会导致 “循环导入” 的
- 只有 1 个地方用到:偏向于局部导入(避免之后的改动引出“循环导入”)
- 多个地方(>= 2 )用到:顶部导入

- 会导致 “循环导入” 的:只能局部导入

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/943795

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX