【问题标题】:Local variables in Python timeit setup [duplicate]Python timeit设置中的局部变量[重复]
【发布时间】:2023-03-12 02:57:02
【问题描述】:

在我读到的所有关于 timeit 的地方,我发现只能以这种方式使用变量:

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。 我想将 timeit.timeit 与它所在范围内的变量一起使用,例如

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

如您所见,我的问题是:

当它们都不在主程序中时,如何将 timeit.timeit 与同一范围内的变量一起使用?

【问题讨论】:

    标签: python string variables scope timeit


    【解决方案1】:

    我想将 timeit.timeit 与它所在范围内的变量一起使用。

    TLDR:

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

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

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

    >>> func()
    0.12512516975402832
    

    说明

    那么在全局范围内,你想使用全局变量,局部变量,局部变量?在全局范围内,locals() 返回与 globals() 相同的结果,因此您将 ', '.join(locals()) 粘贴在 'from __main__ import 'globals() 的末尾,因为它们在全局范围内是等效的:

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

    您也可以使用函数和 globals() 来执行此操作,但您不能使用 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 func():
        s1 = 'abc'
        s2 = 'abc'
        return timeit.timeit(lambda: s1 == s2)
    

    或全功能def:

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

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

    >>> func()
    0.12512516975402832
    

    当它们都不在主程序中时

    如果您想通过设置而不是 __main__ 以外的其他模块加入全局变量,请使用:

    'from ' + __name__ + ' import ' + ', '.join(globals())
    

    【讨论】:

    • 非常感谢您的回答!这很有帮助。
    【解决方案2】:

    正如 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' ) )
    

    【讨论】:

      猜你喜欢
      • 2011-06-25
      • 1970-01-01
      • 2015-08-19
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 2019-04-02
      • 2022-01-07
      相关资源
      最近更新 更多