V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
pppguest3962
V2EX  ›  Python

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

  •  
  •   pppguest3962 · 2023-05-29 10:57:28 +08:00 · 2511 次点击
    这是一个创建于 569 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如:

    # 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 应该不会有坑,
    如果是自写优化不好的函数呢,两种情况用起来会有怎么样的不同?

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

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

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

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

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

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

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

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

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

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

    正面回答:

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

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

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

    - 会导致 “循环导入” 的:只能局部导入
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1338 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 17:32 · PVG 01:32 · LAX 09:32 · JFK 12:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.