I would like to use timeit.timeit with variables that are within the scope it is in.
TLDR:
Use a lambda
closure (so called because it closes over the variables in the function):
def func():
s1 = 'abc'
s2 = 'abc'
return timeit.timeit(lambda: s1 == s2)
And I think that's just about what you're asking for.
>>> func()
0.12512516975402832
Explanation
So in the global scope, you want to use the globals, and local scope, locals? On the global scope, locals()
returns the same as globals()
, so it you ', '.join(locals())
and stick that on the end of 'from __main__ import '
, or globals()
as they're equivalent on the global scope:
>>> s1 = 'abc'
>>> s2 = 'abc'
>>> timeit.timeit('s1==s2', 'from __main__ import ' + ', '.join(globals()))
0.14271061390928885
You could do this with a function and the globals()
too, but you can't use locals():
s1 = 'abc'
s2 = 'abc'
def func():
return timeit.timeit('s1==s2', 'from __main__ import ' + ', '.join(globals()))
and
>>> func()
0.14236921612231157
but the below doesn't work, because you've got to have access to the variables hidden in the local scope of the function, from the import statement:
def func():
s1 = 'abc'
s2 = 'abc'
return timeit.timeit('s1==s2', 'from __main__ import ' + ', '.join(locals()))
But because you can simply pass the function to timeit, what you can do is this:
def func(s1='abc', s2='abc'):
s1 == s2
and
>>> timeit.timeit(func)
0.14399981498718262
So that also means, in your func, you can provide timeit a lambda closure:
def func():
s1 = 'abc'
s2 = 'abc'
return timeit.timeit(lambda: s1 == s2)
Or a full function def:
def func():
s1 = 'abc'
s2 = 'abc'
def closure():
return s1 == s2
return timeit.timeit(closure)
And I think that's just about what you're asking for.
>>> func()
0.12512516975402832
When they're both not in the main program
If you want to join the globals instead with a setup, from other modules than __main__
, use this:
'from ' + __name__ + ' import ' + ', '.join(globals())