在速度和内存效率方面,在函数内导入Python模块和/或函数的优缺点是什么?
是否每次运行该函数时重新导入,或者可能只在开始时重新导入一次,无论函数是否运行?
PEP 8说:
- 导入总是放在文件的顶部,就在任何模块注释和文档字符串之后,以及模块全局变量和常量之前.
在发生时,我违反了PEP 8.有时我会在函数中导入内容.作为一般规则,如果导入仅在单个函数中使用,则执行此操作.
任何意见?
编辑(我觉得导入函数的原因可能是一个好主意):
主要原因:它可以使代码更清晰.
from m import xxx.看到m.xxx这个功能可能会告诉我更多.具体取决于m:它是一个众所周知的顶级模块/包(import m)吗?或者它是一个子模块/包(from a.b.c import m)?我发现了一种新的模式.这种模式是众所周知的还是对它的看法是什么?
基本上,我很难刷新源文件以找出可用的模块导入等等,所以现在,而不是
import foo
from bar.baz import quux
def myFunction():
    foo.this.that(quux)
我将所有导入移动到它们实际使用的函数中,如下所示:
def myFunction():
    import foo
    from bar.baz import quux
    foo.this.that(quux)
这做了一些事情.首先,我很少意外地用其他模块的内容污染我的模块.我可以__all__为模块设置变量,但随后我必须在模块发展时更新它,这对于实际存在于模块中的代码无效.
其次,我很少在我的模块顶部进行一连串的进口,其中一半或更多我不再需要,因为我已经重构了它.最后,我发现这个模式更容易阅读,因为每个引用的名称都在函数体中.
假设我有一个相对较长的模块,但只需要一次外部模块或方法.
在模块中间导入该方法或模块是否可以?
或者应该import只在模块的第一部分.
例:
import string, pythis, pythat
...
...
...
...
def func():
     blah
     blah 
     blah
     from pysomething import foo
     foo()
     etc
     etc 
     etc
...
...
...
请证明您的答案是合理的,并添加指向PEP或相关来源的链接
如果我if __name__ == '__main__'在脚本中使用argparse和测试我也想用作模块,我应该在该测试下导入argparse然后初始化它吗?我没有发现在脚本中使用argparse提到的样式指南,并且许多argparse脚本示例不使用'if name'测试或以不同方式使用它.这是我到目前为止所做的事情:
#! /usr/bin/env python
def main(name):
    print('Hello, %s!' % name)
if __name__ == '__main__':
    import argparse
    parser = argparse.ArgumentParser(description = 'Say hello')
    parser.add_argument('name', help='your name, enter it')
    args = parser.parse_args()
    main(args.name)
我应该使用顶部的其他模块导入argparse并在脚本体中进行配置吗?
在代码中加载模块的位置是否重要?或者它们都应该在顶部声明,因为在加载时,外部模块必须加载,无论它们在代码中声明的位置......?
例:
from os import popen
try:
    popen('echo hi')
    doSomethingIllegal;
except:
    import logging                   #Module called only when needed?
    logging.exception("Record to logger)
或者这是由编译器以与以下相同的方式进行优化:
from os import popen
import logging                      #Module will always loaded regardless
try:
    popen('echo hi')
    doSomethingIllegal;
except:
    logging.exception("Record to logger)
这 两个问题涉及import在函数内部和模块顶部使用.我不需要被说服将我的进口放在首位,这是有充分理由的.但是,为了更好地理解我想要跟进的技术问题.
通过使用闭包并且只在第一次运行时导入,你能否在性能方面获得最佳性能?
具体来说,假设您有以下代码:
import sys
def get_version():
    return sys.version
您希望仅在函数被调用时才进行导入,因此您将其移入:
def get_version():
    import sys
    return sys.version
但现在它是缓慢的,如果它不被调用了很多,所以你尝试一些更复杂的:
def _get_version():
    import sys
    def nested():
        return sys.version
    global get_version
    get_version = nested
    return nested()
get_version = _get_version
现在至少一个基本的性能测试表明这个最后一个选项比第一个选项略慢(大约需要110%),但比第二个选项快得多(大约需要20%).
首先,这实际上有效吗?我的测量是否准确地描述了第二个例子做了更多的工作,或者它是我测量事物的工件.
第二,关闭是否会减速 - 超出第一次运行功能?
PEP 8规定:
导入总是放在文件的顶部,就在任何模块注释和文档字符串之后,以及模块全局变量和常量之前。
但是,如果我正在导入的类/方法/函数仅由子进程使用,那么在需要时进行导入肯定会更有效?我的代码基本上是:
p = multiprocessing.Process(target=main,args=(dump_file,))
p.start()
p.join()
print u"Process ended with exitcode: {}".format(p.exitcode)
if os.path.getsize(dump_file) > 0:
    blc = BugLogClient(listener='http://21.18.25.06:8888/bugLog/listeners/bugLogListenerREST.cfm',appName='main')
    blc.notifyCrash(dump_file)
main() 是主要的应用程序。此函数需要大量导入才能运行,并且会占用一些 ram 空间 (+/- 35MB)。由于应用程序在另一个进程中运行,因此在 PEP 8 之后进行了两次导入(一次由父进程执行,另一次由子进程执行)。还应该注意的是,这个函数应该只被调用一次,因为父进程正在等待查看应用程序是否崩溃并留下退出代码(感谢faulthandler)。所以我在 main 函数中对导入进行了编码,如下所示:
def main(dump_file):
    import shutil
    import locale
    import faulthandler
    from PySide.QtCore import Qt
    from PySide.QtGui import QApplication, QIcon
代替:
import shutil
import locale
import faulthandler
from PySide.QtCore import Qt
from PySide.QtGui import QApplication, QIcon
def main(dump_file):
是否有一种“标准”方式来处理使用多处理完成的导入?
PS:我看过这个姐妹的问题
“PyCharm 知道在测试中您会在单元测试中而不是在模块启动时进行导入”是“PyCharm 7/8 入门:测试”视频中关于PyCharm提供的测试功能的引用。
来自PEP8:
导入始终放在文件的顶部,紧接在任何模块注释和文档字符串之后,以及模块全局变量和常量之前。
在另一个 SO 问题中,在 python 中导入的位置的概念已经作为一个 broder 概念得到解决。但是,没有提及单元测试时的特殊情况。
通过导入内部测试而不是在模块开始时导入,我们可以获得什么优势?
如果不同的测试使用相同的模块,是否每次都需要导入该模块?
我是一名初级编码员,我最近创建了一个函数,该函数接受一个字符串并随机将每个字母大写。
def rand_upper(string):
    import random
    strList = [l for l in string.lower()] 
    newList = []
    for i in strList:
        j = random.randrange(2)
        if j == 1:
            letter = i.upper()
            newList.append(letter)
        else:
            newList.append(i)
    return "".join(newList)
该代码按我的意图工作,但是有什么方法可以使此代码更清晰吗?我个人认为这很难阅读。有没有其他方法可以压缩代码以使其更具可读性/效率?谢谢!
python ×10
import ×2
closures ×1
coding-style ×1
conventions ×1
optimization ×1
pycharm ×1
runtime ×1
scripting ×1
unit-testing ×1