Python 我们可以在同一个模块中运行多个函数吗

Python 我们可以在同一个模块中运行多个函数吗,python,timeit,Python,Timeit,我想在同一个Python模块中编写多个函数,每个函数都是使用timeit的单独评测测试,因此我可以使用命令行参数指定要运行的函数。一个简单的例子(profiling.py)是: import sys import timeit def foo(): setup = """ import random """ foo_1 = """ for i in range(1000): random.randint(0, 99) + random

我想在同一个Python模块中编写多个函数,每个函数都是使用
timeit
的单独评测测试,因此我可以使用命令行参数指定要运行的函数。一个简单的例子(profiling.py)是:

import sys
import timeit

def foo():

    setup = """
    import random
    """

    foo_1 = """
    for i in range(1000):
        random.randint(0, 99) + random.randint(0, 99)
    """

    foo_2 = """
    for i in range(1000):
        random.randint(0, 99) + random.randint(0, 99)
    """

    foo_3 = """
    for i in range(1000):
        random.randint(0, 99) + random.randint(0, 99)
    """

    print 'foo_1', timeit.Timer(foo_1, setup).timeit(1000)
    print 'foo_2', timeit.Timer(foo_2, setup).timeit(1000)
    print 'foo_3', timeit.Timer(foo_3, setup).timeit(1000)

if __name__ == '__main__':
    if (len(sys.argv) > 1):
        if (sys.argv[1] == 'foo'):
            foo()
    else:
        print 'Which profiling do you want to run?'
        print 'available:'
        print '    foo'
但是,当我尝试
python profiling.py foo
时,会出现如下错误:

foo_1
Traceback (most recent call last):
  File "profiling.py", line 32, in <module>
    foo()
  File "profiling.py", line 25, in foo
    print 'foo_1', timeit.Timer(foo_1, setup).timeit(1000)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/timeit.py", line 136, in __init__
    code = compile(src, dummy_src_name, "exec")
  File "<timeit-src>", line 6
    _t0 = _timer()
                 ^
IndentationError: unindent does not match any outer indentation level
foo_1
回溯(最近一次呼叫最后一次):
文件“profiling.py”,第32行,在
foo()
文件“profiling.py”,第25行,在foo中
打印'foo_1',timeit.Timer(foo_1,setup).timeit(1000)
文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/timeit.py”,第136行,在__
代码=编译(src,dummy\u src\u name,“exec”)
文件“”,第6行
_t0=_计时器()
^
缩进错误:未缩进与任何外部缩进级别不匹配
我在代码中搜索了常见的空格/制表符缩进错误,但没有找到任何错误。因此,我想知道这是否是因为我在函数中包装了一个
timeit
测试,而这是不允许的?

这是有效的:

import sys
import timeit

def foo():

    setup = """
import random
"""

    foo_1 = """
for i in range(1000):
    random.randint(0, 99) + random.randint(0, 99)
"""

    foo_2 = """
for i in range(1000):
    random.randint(0, 99) + random.randint(0, 99)
"""

    foo_3 = """
for i in range(1000):
    random.randint(0, 99) + random.randint(0, 99)
"""

    print 'foo_1', timeit.Timer(foo_1, setup).timeit(1000)
    print 'foo_2', timeit.Timer(foo_2, setup).timeit(1000)
    print 'foo_3', timeit.Timer(foo_3, setup).timeit(1000)

if __name__ == '__main__':
    if (len(sys.argv) > 1):
        if (sys.argv[1] == 'foo'):
            foo()
    else:
        print 'Which profiling do you want to run?'
        print 'available:'
        print '    foo'
问题是,您作为
setup
foo_1
等传递的字符串是缩进的,因为您在函数中已将它们与缩进的代码对齐。但是,当该字符串在
timeit
执行时,会引发缩进错误,因为代码不应缩进。这基本上是相同的事情会发生,如果你尝试

exec("    import sys")

作为交互式口译员会话的第一件事。

mgilson给出了一个很好的答案。但就我个人而言,我发现herdoc字符串中的视觉去中心化的线条分散了我的注意力。它也会断裂

通过分别编写行并将它们连接起来,可以获得相同的效果,如下所示:

import sys
import timeit


def foo():

    setup = 'import random'

    foo_1 = '\n'.join([
        'for i in range(1000):',
        '    random.randint(0, 99) + random.randint(0, 99)',
    ])

    foo_2 = '\n'.join([
        'for i in range(1000):',
        '    random.randint(0, 99) + random.randint(0, 99)',
    ])

    foo_3 = '\n'.join([
        'for i in range(1000):',
        '    random.randint(0, 99) + random.randint(0, 99)',
    ])

    print 'foo_1', timeit.Timer(foo_1, setup).timeit(1000)
    print 'foo_2', timeit.Timer(foo_2, setup).timeit(1000)
    print 'foo_3', timeit.Timer(foo_3, setup).timeit(1000)

if __name__ == '__main__':
    if (len(sys.argv) > 1):
        if (sys.argv[1] == 'foo'):
            foo()
    else:
        print 'Which profiling do you want to run?'
        print 'available:'
        print '    foo'

您在每行上获得的空间较少,但我认为折衷对我来说是值得的。

如果您从传递给timeit的字符串中删除空白,会发生什么情况?(例如,
foo_1=“对于范围(1000)内的i:\n random.randint(0,99)+random.randint(0,99)”
)您是否有机会复制并粘贴该行?很多时候,当您复制和粘贴时,由于选项卡大小不匹配或选项卡为空白,您会遇到该错误。谢谢您的建议。因此,我可以通过执行
setup=“”import random”“”
(全部在一行中)来修复错误,而无需对foo_1进行任何更改。我想知道为什么?
timeit
必须对要运行的参数进行一些“清理”,但不能对安装程序代码进行清理。@MLister这有什么好笑的?您的设置代码前面没有任何缩进——只有一个换行符(在python中,空行是完全可以接受的)。谢谢你指出。