5

我想在同一个 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

我在代码中搜索了通常的空格/制表符缩进错误,但没有找到。因此我想知道是不是因为我timeit在函数中包装了一个测试,这是不允许的?

4

2 回答 2

7

这有效:

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'

问题是您传递为setupandfoo_1等的字符串是缩进的,因为您已将它们与函数内的缩进代码对齐。但是,当该字符串由 执行时timeit,它会引发您看到的缩进错误,因为代码不应缩进。如果您尝试过,这基本上与发生的事情相同...

exec("    import sys")

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

于 2012-06-04T19:37:10.093 回答
0

mgilson 给出了一个很好的答案。但就个人而言,我发现heredoc 字符串中视觉上凹陷的线条令人分心。它还破坏了我使用的 vim python 代码折叠

您可以通过单独编写行并加入它们来获得相同的效果,如下所示:

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'

你在每条线上得到的空间更少,但我的权衡对我来说是值得的。

于 2014-05-26T17:18:23.713 回答