代码之家  ›  专栏  ›  技术社区  ›  pystudent

Python timeit设置中的局部变量[重复]

  •  18
  • pystudent  · 技术社区  · 11 年前

    在我读到的关于时间的所有地方,我发现我只能这样使用变量:

    s1 = 'abc'
    s2 = 'abc'
    timeit.timeit('s1==s2', 'from __main__ import s1, s2', number=10**4)
    

    s1 = 'abc'
    s2 = 'abc'
    def func():
        timeit.time('s1==s2', 'from __main__ import s1,s2', number=10**4)
    

    这意味着你也可以使用timeit。只要变量在主程序中,就可以在函数中计时。 我想利用时间。例如,timeit包含在其范围内的变量 :

    def func():
        s1 = 'abc'
        s2 = 'abc'
        timeit.timeit(...)
    

    如你所见,我的问题是:

    我怎样才能使用timeit。当变量都不在主程序中时,使用同一范围内的变量计时?

    2 回复  |  直到 11 年前
        1
  •  21
  •   Aaron Hall    11 年前

    我想利用时间。使用在其范围内的变量计时。

    TLDR:

    使用 lambda 闭包(之所以称为闭包,是因为它关闭函数中的变量):

    def func():
        s1 = 'abc'
        s2 = 'abc'
        return timeit.timeit(lambda: s1 == s2)
    

    我认为这正是你所要求的。

    >>> func()
    0.12512516975402832
    

    解释

    所以在全局范围内,你想使用全局范围和局部范围,局部范围?在全球范围内, locals() 返回的值与 globals() ,所以你 ', '.join(locals()) 把它贴在 'from __main__ import ' 全局() 因为它们在全球范围内是等价的:

    >>> s1 = 'abc'
    >>> s2 = 'abc'
    >>> timeit.timeit('s1==s2', 'from __main__ import ' + ', '.join(globals()))
    0.14271061390928885
    

    您可以使用函数和 全局() 也是,但不能使用locals():

    s1 = 'abc'
    s2 = 'abc'
    def func():
        return timeit.timeit('s1==s2', 'from __main__ import ' + ', '.join(globals()))
    

    >>> func()
    0.14236921612231157
    

    但下面的方法不起作用,因为您必须通过import语句访问隐藏在函数局部范围中的变量:

    def func():
        s1 = 'abc'
        s2 = 'abc'
        return timeit.timeit('s1==s2', 'from __main__ import ' + ', '.join(locals()))
    

    但因为您可以简单地将函数传递给timeit 可以 是这样的:

    def func(s1='abc', s2='abc'):
        s1 == s2
    

    >>> timeit.timeit(func)
    0.14399981498718262
    

    这也意味着,在func中,可以为timeit提供lambda闭包:

    def函数():
    s1=“abc”
    s2=“abc”
    返回时间。时间(λ:s1==s2)
    

    或完整函数def:

    def func():
        s1 = 'abc'
        s2 = 'abc'
        def closure():
            return s1 == s2
        return timeit.timeit(closure)
    

    我认为这正是你所要求的。

    >>>函数()
    0.12512516975402832
    

    当他们都不在主程序中时

    如果您希望通过设置而不是从其他模块加入全局 __main__ ,使用此项:

    'from ' + __name__ + ' import ' + ', '.join(globals())
    
        2
  •  4
  •   loopbackbee    11 年前

    正如jonrsharpe所解释的,在 timeit 访问范围 something outside its scope that is not a global .

    你应该考虑重写你的函数,将它需要使用的变量作为参数- 使用全局变量通常被认为是一种糟糕的做法,会导致很多问题 .

    为了向 timeit.timeit ,可以使用 partial function :

    from functools import partial
    
    def func(s1,s2):
        pass
    
    timeit.timeit( partial( func, s1='bla', s2='bla' ) )