Python Timeit и «глобальное имя не определено»

У меня проблема с функцией timit для оптимизации кода. Например, я пишу функции с параметрами в файл, назовем его myfunctions.py, содержащий:

def func1(X):
    Y = X+1
    return Y

и я тестирую эту функцию во втором файле test.py, где я вызываю функцию таймера для проверки производительности кода (очевидно, в более сложных задачах!), содержащего:

import myfunctions
X0 = 1
t = Timer("Y0 = myfunctions.func1(X0)")
print Y0
print t.timeit()

Y0 не вычисляется, и даже если я прокомментирую строку print Y0, ошибка global name 'myfunctions' is not defined произошла.

Если я укажу настройку с помощью команды

t = Timer("Y0 = myfunctions.func1(X0)","import myfunctions")

теперь произошла ошибка global name 'X0' is not defined.

Кто-нибудь знает, как это решить? Большое спасибо.


person cedm34    schedule 04.01.2012    source источник
comment
Возможный дубликат Получение глобального имени 'foo' не определено с Python timeit   -  person sds    schedule 20.09.2017


Ответы (2)


Вам нужен setup параметр. Пытаться:

Timer("Y0 = myfunctions.func1(X0)", setup="import myfunctions; X0 = 1")
person Roman Bodnarchuk    schedule 04.01.2012
comment
Как я уже упоминал в вопросе, это возвращает ошибку, глобальное имя 'X0' не определено - person cedm34; 04.01.2012
comment
Глобальная ошибка давно исчезла. Но это не создает значения Y0. Есть решение для? - person cedm34; 04.01.2012

Причина, по которой Y0 не определена, заключается в том, что вы определили это в строке, но во время синтаксического анализа в начале выполнения строка еще не оценивается, чтобы оживить переменную. Так что поместите Y0 = 0 где-нибудь в верхней части вашего скрипта, чтобы он был определен заранее.

Все внешние функции и переменные должны быть переданы Timer с использованием его аргумента setup. Таким образом, вам нужно "import myfunctions; X0 = 1" в качестве параметра настройки.

Это будет работать:

from timeit import Timer
import myfunctions
X0 = 1
Y0 = 0     #Have Y0 defined
t = Timer("Y0 = myfunctions.func1(X0)", "import myfunctions; X0 = %i" % (X0,))
print t.timeit()
print Y0

Посмотрите, как я использовал "X0 = %i" % (X0,) для передачи реального значения внешней переменной X0.

Еще одна вещь, которую вы, возможно, захотите знать, это то, что если в вашем основном файле есть какие-либо функции, которые вы хотите использовать в timeit, вы можете timeit распознавать их, передав from __main__ import * в качестве второго аргумента.


Если вы хотите, чтобы timeit могла изменять ваши переменные, вам не следует передавать им строки. Для более удобного использования вы можете передавать ему вызываемые объекты. Вы должны передать вызываемый объект, который изменяет желаемую переменную. Тогда тебе не нужно setup. Смотреть:

from timeit import Timer
import myfunctions

def measure_me():
    global Y0    #Make measure_me able to modify Y0
    Y0 = myfunctions.func1(X0)

X0 = 1
Y0 = 0     #Have Y0 defined
t = Timer(measure_me)
print t.timeit()
print Y0

Как видите, я поставил print Y0 после print t.timeit(), так как перед выполнением вы не можете изменить его значение!

person Hossein    schedule 04.01.2012