Как пройти параметры функции при использовании timeit.timer () -- python поле с участием timer пол Связанный проблема

how to pass parameters of a function when using timeit.Timer()


52
vote

проблема

русский

Это план простая программа

 <код> # some pre-defined constants A = 1 B = 2  # function that does something critical def foo(num1, num2):     # do something  # main program.... do something to A and B for i in range(20):     # do something to A and B     # and update A and B during each iteration  import timeit t = timeit.Timer(stmt="foo(num1,num2)")   print t.timeit(5)   

Я просто продолжаю получать "Global Name Foo не определен" ..... Может кто-нибудь помочь мне на этом? Спасибо!

Английский оригинал

This is the outline of a simple program

# some pre-defined constants A = 1 B = 2  # function that does something critical def foo(num1, num2):     # do something  # main program.... do something to A and B for i in range(20):     # do something to A and B     # and update A and B during each iteration  import timeit t = timeit.Timer(stmt="foo(num1,num2)")   print t.timeit(5) 

I just keep getting "global name foo is not defined"..... Can anyone help me on this? Thanks!

</div
     
       
       

Список ответов

16
 
vote
vote
Лучший ответ
 

Кодовые фрагменты должны быть автономными - они не могут сделать внешние ссылки. Вы должны определить ваши значения в строке оператора или строки настройки:

 <код> import timeit  setup = """ A = 1 B = 2  def foo(num1, num2):     pass  def mainprog():     global A,B     for i in range(20):         # do something to A and B         foo(A, B) """  t = timeit.Timer(stmt="mainprog()" setup=setup) print(t.timeit(5))   

еще лучше, перепишите свой код, чтобы не использовать глобальные значения.

 

The code snippets must be self-contained - they cannot make external references. You must define your values in the statement-string or setup-string:

import timeit  setup = """ A = 1 B = 2  def foo(num1, num2):     pass  def mainprog():     global A,B     for i in range(20):         # do something to A and B         foo(A, B) """  t = timeit.Timer(stmt="mainprog()" setup=setup) print(t.timeit(5)) 

Better yet, rewrite your code to not use global values.

</div
 
 
 
 
61
 
vote

Функции могут использовать аргументы в <Код> timeit Если они созданы с использованием замыканий, мы можем добавить это поведение, упаковывая их в другую функцию.

 <код> def foo(num1, num2):     def _foo():         # do something to num1 and num2         pass     return _foo  A = 1 B = 2  import timeit t = timeit.Timer(foo(A,B))   print(t.timeit(5))   

или короче, мы можем использовать functools.partial вместо явных закрытых Декларация

 <код> def foo(num1, num2):     # do something to num1 and num2     pass  A = 1 B = 2  import timeit, functools t = timeit.Timer(functools.partial(foo, A, B))  print(t.timeit(5))   

<Сильные> редактировать с помощью лямбда, спасибо @jupiterbjy

Мы можем использовать функцию лямбда без параметров вместо библиотеки functools

 <код> def foo(num1, num2):     # do something to num1 and num2     pass  A = 1 B = 2  import timeit t = timeit.Timer(lambda: foo(A, B))  print (t.timeit(5))   
 

The functions can use arguments in timeit if these are created using closures, we can add this behaviours by wrapping them in another function.

def foo(num1, num2):     def _foo():         # do something to num1 and num2         pass     return _foo  A = 1 B = 2  import timeit t = timeit.Timer(foo(A,B))   print(t.timeit(5)) 

or shorter, we can use functools.partial instead of explicit closures declaration

def foo(num1, num2):     # do something to num1 and num2     pass  A = 1 B = 2  import timeit, functools t = timeit.Timer(functools.partial(foo, A, B))  print(t.timeit(5)) 

EDIT using lambda, thanks @jupiterbjy

we can use lambda function without parameters instead of functools library

def foo(num1, num2):     # do something to num1 and num2     pass  A = 1 B = 2  import timeit t = timeit.Timer(lambda: foo(A, B))  print (t.timeit(5)) 
</div
 
 
         
         
15
 
vote

Предложите, чтобы ваш модуль имени файла test.py

 <код> # some pre-defined constants A = 1 B = 2  # function that does something critical def foo(n, m):     pass  # main program.... do something to A and B for i in range(20):     pass  import timeit t = timeit.Timer(stmt="test.foo(test.A, test.B)", setup="import test")   print t.timeit(5)   
 

Supposing that your module filename is test.py

# some pre-defined constants A = 1 B = 2  # function that does something critical def foo(n, m):     pass  # main program.... do something to A and B for i in range(20):     pass  import timeit t = timeit.Timer(stmt="test.foo(test.A, test.B)", setup="import test")   print t.timeit(5) 
</div
 
 
9
 
vote

Ваша функция должна быть определена в строке установки. Хороший способ сделать это, настроив свой код в модуле, поэтому вы просто должны делать

 <код> t = timeit.Timer("foo(num1, num2)", "from myfile import foo") t.timeit(5)   

В противном случае вам придется определить всю настройку в виде строки внутри оператора настройки.

 <код> setup = """  # some pre-defined constants A = 1 B = 2  # function that does something critical def foo(num1, num2):     # do something  # main program.... do something to A and B for i in range(20):     # do something to A and B     # and update A and B during each iteration """  t = timeit.Timer("foo(num1, num2)", setup) t.timeit(5)   

Что-то удивительное, что я только что узнал, это ярлык для iPython, который использует CPROFIL.

 <код> def foo(x, y):     print x*y  %prun foo("foo", 100)   
 

Your function needs to be define in the setup string. A good way to do this is by setting up your code in a module, so you simple have to do

t = timeit.Timer("foo(num1, num2)", "from myfile import foo") t.timeit(5) 

Otherwise, you'll have to define all of the setup as a string inside the setup statement.

setup = """  # some pre-defined constants A = 1 B = 2  # function that does something critical def foo(num1, num2):     # do something  # main program.... do something to A and B for i in range(20):     # do something to A and B     # and update A and B during each iteration """  t = timeit.Timer("foo(num1, num2)", setup) t.timeit(5) 

Something awesome I just found out about is a shortcut for iPython that uses cProfile.

def foo(x, y):     print x*y  %prun foo("foo", 100) 
</div
 
 
9
 
vote

Я обычно создаю дополнительную функцию:

 <код> def f(x,y):     return x*y  v1 = 10 v2 = 20  def f_test():     f(v1,v2)  print(timeit.timeit("f_test()", setup="from __main__ import f_test"))   
 

I usually create an extra function:

def f(x,y):     return x*y  v1 = 10 v2 = 20  def f_test():     f(v1,v2)  print(timeit.timeit("f_test()", setup="from __main__ import f_test")) 
</div
 
 
 
 
5
 
vote

Существует гораздо более простое решение (по крайней мере, для Python 3), вы можете привести к выполнению кода в вашем текущем глобальном пространстве имен:

<Код> t = timeit.Timer(stmt="foo(num1,num2)", globals=globals())

https://docs.ython.org/3/library/imeyit. HTML # Примеры Я знаю, что глобалы не являются предпочтительными, но если вы просто делаете быстрый скрипт, чтобы проверить что-то, я думаю, что это самая простая реализация.

 

There is a much simpler solution (at least for Python 3), you can cause the code to be executed within your current global namespace:

t = timeit.Timer(stmt="foo(num1,num2)", globals=globals())

https://docs.python.org/3/library/timeit.html#examples I know globals are not preferred, but if you are just making a quick script to check something I think this is the easiest implementation.

</div
 
 
 
 
5
 
vote

Другой вариант - связывать функцию к своим аргументам через functools < / a> (похоже на std :: bind). Тогда вам не нужно проходить аргументы в Timeit, Callable возвращается functool.partial :

 <код>     def findMax(n):#n is an array         m = 0         c = 0         for i in range(len(n)):             c += 1             if m < n[i]:                 m = n[i]         return m, c   import timeit import functools a = [6, 2, 9, 3, 7, 4, 5] t = timeit.Timer(functools.partial(findMax,a)) t.timeit(100)   
 

Another option is to bind the function to its arguments via functools (similar to std::bind). Then you don't need to pass arguments to timeit, the callable returned by functool.partial takes care of that:

    def findMax(n):#n is an array         m = 0         c = 0         for i in range(len(n)):             c += 1             if m < n[i]:                 m = n[i]         return m, c   import timeit import functools a = [6, 2, 9, 3, 7, 4, 5] t = timeit.Timer(functools.partial(findMax,a)) t.timeit(100) 
</div
 
 
 
 
2
 
vote

Вот пример того, как разделять процедуру синхронизации, не вызывая глобал

 <код> def foo(a, b):     '''Do something to `a` and `b`'''     return a + b  def time_foo():     '''Create timer object simply without using global variables'''     import timeit      _foo = foo     a = 1     b = 2      # Get `Timer` oject, alternatively just get time with `timeit.timeit()`     t = timeit.Timer('_foo(a, b)', globals=locals())      return t   

Вы можете даже обобщить это, если вы хотите использовать один и тот же <код> timeit функцию для других функций. Вот пример с вашим примером <Код> main() Рутина:

 <код> def foo1(a, b):     '''Add `a` and `b`'''     return a + b  def foo2(a, b):     '''More math on `a` and `b`'''     return (a**2 * b)**2  def time_foo(func, **kwargs):     '''Create timer object simply without using global variables'''     import timeit     return timeit.timeit('func(**kwargs)', globals=locals())  def run():     '''Modify inputs to foo and see affect on execution time'''      a = 1     b = 2     for i in range(10):         # Update `a` and `b`         a += 1         b += 2         # Pass args to foo as **kwargs dict         print('foo1 time: ', time_foo(foo1, **{'a':a, 'b':b}))         print('foo2 time: ', time_foo(foo2, **{'a':a, 'b':b}))      return None   
 

Here is an example of how to compartmentalize the timing routine, without calling globals

def foo(a, b):     '''Do something to `a` and `b`'''     return a + b  def time_foo():     '''Create timer object simply without using global variables'''     import timeit      _foo = foo     a = 1     b = 2      # Get `Timer` oject, alternatively just get time with `timeit.timeit()`     t = timeit.Timer('_foo(a, b)', globals=locals())      return t 

You could even generalize this if you wanted to use the same timeit function to time other functions. Here is an example with your example main() routine:

def foo1(a, b):     '''Add `a` and `b`'''     return a + b  def foo2(a, b):     '''More math on `a` and `b`'''     return (a**2 * b)**2  def time_foo(func, **kwargs):     '''Create timer object simply without using global variables'''     import timeit     return timeit.timeit('func(**kwargs)', globals=locals())  def run():     '''Modify inputs to foo and see affect on execution time'''      a = 1     b = 2     for i in range(10):         # Update `a` and `b`         a += 1         b += 2         # Pass args to foo as **kwargs dict         print('foo1 time: ', time_foo(foo1, **{'a':a, 'b':b}))         print('foo2 time: ', time_foo(foo2, **{'a':a, 'b':b}))      return None 
</div
 
 
0
 
vote

Я предпочитаю создание static класса со всеми данными, готовыми к получению до запуска таймера.

Другое примечание, лучше делать тесты в функции, а затем в глобальном пространстве, так как глобальное пространство не пользуется преимуществом FAST_LOAD Почему код Python работает быстрее в функции?

 <код> t = timeit.Timer(stmt="foo(num1,num2)", globals=globals())0  
 

I prefer creating a static class with all the Data ready to be picked up prior of running the timer.

Another note, it is better to do test runs in function rather then in the global space, as the global space isn't taking advantage of FAST_LOAD Why does Python code run faster in a function?

class Data(object):     """Data Creation"""     x = [i for i in range(0, 10000)]     y = tuple([i for i in range(0, 10000)])     def __init__(self):         pass  import timeit  def testIterator(x):     for i in range(10000):         z = i   print timeit.timeit("testIterator(Data.x)", setup="from __main__ import testIterator, Data", number=50) print timeit.timeit("testIterator(Data.y)", setup="from __main__ import testIterator, Data", number=50) 
</div
 
 
0
 
vote

Это должно работать:

 <код> t = timeit.Timer(stmt="foo(num1,num2)", globals=globals())1  
 

This should work:

import timeit  def f(x,y):     return x*y  x = 5 y = 7  print(timeit.timeit(stmt='f(x,y)',                     setup='from __main__ import f, x, y',                     number=1000)) 
</div
 
 
0
 
vote

Я играл с синхронизацией в Python 3.7 сегодня и пытается пройти функции и переменные в таймер. Это то, с чем я придумал.

 <код> t = timeit.Timer(stmt="foo(num1,num2)", globals=globals())2  

Это выходы:

Regex: 1.378352418
Это тест системы аварийного вещания

LOOP_IRY: 0.1585895029999997
Это тест чрезвычайной ситуации Вещательная система

Тогда все, что нужно для проверки новой версии, добавляет в новую функцию. Что-то вроде:

 <код> t = timeit.Timer(stmt="foo(num1,num2)", globals=globals())3  

Теперь он выводит:

Regex: 1.378352418
Это тест системы аварийного вещания

LOOP_IRY: 0.1585895029999997
Это тест системы аварийного вещания

split_join: 0.05700970800000005
Это тест системы аварийного вещания

 

I was playing around with timing in Python 3.7 today and trying to pass functions and variables into the timer. This is what I came up with.

import re  text = "This         is      a  test of the      emergency broadcast       system"  def regex(text):     return re.sub(r"(s)1{1,}", r"1", text)  def loop_while(text):     if "  " in text:         while "  " in text:             text = text.replace("  ", " ")      return text  if __name__ == "__main__":     import timeit      callable_functions = [item for item in locals().items() if callable(item[1])]      for func_name, func in callable_functions:         elapsed_time = timeit.timeit(f"{func_name}(text)", globals=globals(), number=100000)         print(f"{func_name}: {elapsed_time}  {func(text)} ") 

This outputs:

regex: 1.378352418
This is a test of the emergency broadcast system

loop_while: 0.15858950299999997
This is a test of the emergency broadcast system

Then all it takes to test a new version is adding in a new function. Something like:

def split_join(text):     return " ".join(text.split()) 

Now it outputs:

regex: 1.378352418
This is a test of the emergency broadcast system

loop_while: 0.15858950299999997
This is a test of the emergency broadcast system

split_join: 0.05700970800000005
This is a test of the emergency broadcast system

</div
 
 
0
 
vote

Вы должны создать переменную в строке установки. Здесь я импортирую функцию и создаю одну из переменных, которые я передаю к нему. Я также устанавливаю одну из переменных, бросив его на строку STMT

 <код> t = timeit.Timer(stmt="foo(num1,num2)", globals=globals())4  
 

You have to create the variable within the setup string. Here I import the function, and create one of the variables that i pass to it. I also set one of the variables by casting it to the stmt string

SETUP = ''' from __main__ import policy_iteration from environments.gridworld import GridworldEnv  env = GridworldEnv() '''  discount = 5 timeit.timeit("policy_iteration(env,discount_factor="+str(discount)+")",                           setup= SETUP,                           number=10)) 
</div
 
 

Связанный проблема

0  Почему мой скрипт Cron работает только один раз?  ( Why my cron script running just once ) 
Я пытаюсь запустить простой сценарий Python, используя команды cron. Я написал код, чтобы запускать свой скрипт Python в каждом 1 минуте и записывать вывод в ...

1  dataframe или sqlctx (sqlcontext) сгенерировали "попытка вызвать пакет" ошибка  ( Dataframe or sqlctx sqlcontext generated trying to call a package error ) 
Я использую Spark 1.3.1. В Pyspark я создал Dataframe от RDD и зарегистрировал схему, что-то вроде этого: <код> dataLen=sqlCtx.createDataFrame(myrdd, ["id",...

2  Использование OpenPyXL для поиска ячейки в одном столбце, а затем для распечатки строки для этой соответствующей ячейки  ( Using openpyxl to search for a cell in one column and then to print out the row ) 
Например, я хочу иметь возможность вводить в мою программу через пользователь ввода данных, а затем распечатать ряд, относящуюся к этой ячейке. В идеале, если...

0  Как умножить диагональные элементы друг другом, используя numpy?  ( How to multiply diagonal elements by each other using numpy ) 
Для целей этого упражнения давайте рассмотрим матрицу, где элемент <код> m_{i, j} дается правилом <код> m_{i, j} = i*j Если <код> i == j и <код > 0 else. ...

0  Как написать Pivot_Table в TXT файл Python  ( How to write the pivot table to txt file by python ) 
Я получаю pivot_table следующим образом: Есть места в таблице, Что я хочу написать на TXT: Как получить это? <код> WKWebView0 ...

25  Найти сломанные симличины с Python  ( Find broken symlinks with python ) 
Если я звоню <код> os.stat() на сломанный <код> 9988777663 , python бросает <код> OSError исключение. Это делает его полезным для их поиска. Тем не менее, е...

1  Вызов функции Python с параметрами из скрипта оболочки  ( Calling a python function with options from shell script ) 
У меня есть сценарий Python, который принимает различные варианты из командной строки e.g. -Runs с графическим интерфейсом <код> python myscript.py -gui...

0  Как можно включить против псевдонима в Pyqtgraph ImageView?  ( How can anti aliasing be enabled in a pyqtgraph imageview ) 
Я использую <код> pyqtgraph 's <код> ImageView widget, чтобы отобразить изображение, которое необходимо масштабировать в 1,25 до 1,5, чтобы быть удобным. Эт...

1  Создание метода класса Python с использованием закрытия  ( Creating a python class method using a closure ) 
Я использую модуль unittest unittest module (как я довольно новый python), и я оказываюсь, что вы выполняете те же утверждения испытаний снова и снова. Я х...

2  Создание кафельной карты с блендером  ( Creating a tiled map with blender ) 
Я смотрю на создание плитки карты на основе 3D-модели, сделанной в Blender, карта 16 х 16 в блендере. У меня есть 4 разных уровня зума, и каждая плитка со...

2  Heroku Установить Letsencrypt - SU: ДОЛЖЕН БУДЬТ  ( Heroku install letsencrypt su must be run from a terminal ) 
Я пытаюсь создать сертификат SSL для Мой сайт , чтобы получить зеленый замок. . Во время передачи, как это сделать (никогда не делал ничего с сертификатами ...

1  Cprofile принимает много памяти  ( Cprofile taking a lot of memory ) 
Я пытаюсь профилировать мой проект в Python, но у меня заканчивается память. Сам мой проект довольно памяти, но даже пробеги полумана с возможностью погибан...

33  Argparse «Обязательные» необязательные аргументы  ( Argparse compulsory optional arguments ) 
argparse модуль имеет то, что называются «дополнительными» аргументами. Все аргументы, имя которого начинается с <код> - или <код> -- необязательно по умо...

0  Python получает глобальные модули вместо местных внутри виртуальны  ( Python is getting global modules instead of local ones inside of virtualenv ) 
Это мой первый раз, используя virtualenv и mysqldb, и я получаю странную ошибку. После того, как я настрою этот Virtualenv, я установил MySQLDB изнутри Virtua...

1  Python: Tkinter не отображает мой образ или интерфейс  ( Python tkinter not displaying my image or ui ) 
Я пытаюсь создать пользовательский интерфейс с изображением в правом верхнем углу. Вот мой код: <код> import tkinter as tk import urllib.request import base...

Связанный проблема

0  Почему мой скрипт Cron работает только один раз? 
1  dataframe или sqlctx (sqlcontext) сгенерировали "попытка вызвать пакет" ошибка 
2  Использование OpenPyXL для поиска ячейки в одном столбце, а затем для распечатки строки для этой соответствующей ячейки 
0  Как умножить диагональные элементы друг другом, используя numpy? 
0  Как написать Pivot_Table в TXT файл Python 
25  Найти сломанные симличины с Python 
1  Вызов функции Python с параметрами из скрипта оболочки 
0  Как можно включить против псевдонима в Pyqtgraph ImageView? 
1  Создание метода класса Python с использованием закрытия 
2  Создание кафельной карты с блендером 
2  Heroku Установить Letsencrypt - SU: ДОЛЖЕН БУДЬТ 
1  Cprofile принимает много памяти 
33  Argparse «Обязательные» необязательные аргументы 
0  Python получает глобальные модули вместо местных внутри виртуальны 
1  Python: Tkinter не отображает мой образ или интерфейс 



© 2021 www.qaru.top All Rights Reserved. Q&A House все права защищены


Licensed under cc by-sa 3.0 with attribution required.