Как можно удалить встроенные модули Python? min() исчезает при вызове определенной функции

Сегодня я столкнулся со странной ошибкой встроенной функции min(). Я заметил, что он перезаписывается во время выполнения моей программы, поэтому я начал искать в каждой функции стека, когда min() перезаписывается (print(min.__module__)), и я получил UnboundLocalError: локальная переменная 'min', на которую ссылались раньше присваивание Я все еще занимаюсь отладкой и переключаюсь между коммитами, чтобы проверить, что вызывает проблему. Программа зависит от разных модулей, но модули такие же, как и в прошлый раз, когда программа была успешной.

Интересно, а как можно удалить встроенную "мин"? Я уверен, что не объявлял ни одной переменной с таким именем, и даже если бы это было так, ошибка была бы другой. del min должен восстановить встроенный (но в моем случае я получаю ошибку выше) встроенные['min'] работают (в 2 из 3 систем, где я пробовал)

Любая идея о том, как это возможно?


person lib    schedule 06.02.2015    source источник


Ответы (2)


Как правило, причина local variable referenced before assignment не в том, что кто-то удалил min, а в том, что вы присвоили значение переменной с именем min где-то в своей функции после точки, в которой вы получили эту ошибку. (Назначение также может быть в ветке if, которая не была выполнена до ошибки, но, по моему опыту, более вероятен первый предложенный мной сценарий.)

Поскольку вы присвоили ему значение где-то в функции и не объявили его глобальным, это локальная переменная внутри этой функции, и все ее применения относятся к этой локальной переменной, а не к встроенной функции. Однако вы еще не присвоили ему значение, поэтому Python не знает, какое значение вы хотите, чтобы оно имело.

Пример:

def test():
     x = min(1, 2, 3)                   # error message here
     y = max(1, 2, 3)
     # ... lots of code might go here
     min = x if x < y else y            # local assignment here

test()

Решение простое. Не делай этого. Используйте для своей переменной имя, отличное от min. Фактически, именно по этой причине рекомендуется избегать использования имен встроенных модулей в собственных целях.

person kindall    schedule 06.02.2015
comment
Решение простое. Не делайте этого. Настоящий программист — даже его ответы в высшей степени пригодны для повторного использования! СУХОЙ действительно - person Adam Smith; 06.02.2015
comment
@kindall Может ли третий сценарий быть чем-то вроде передачи min (a, b) в качестве аргумента функции (которая, возможно, изменяет свои аргументы) или в качестве значения словаря? Я точно не подобрал это название, я даже искал его во всех файлах проекта! - person lib; 06.02.2015
comment
Не должен. Публикация только кода функции, в которой вы действительно получаете ошибку, поможет нам определить ее. - person kindall; 06.02.2015
comment
Я нашел вызывающую функцию, проблема в том, что она довольно длинная, и это функция вверху — своего рода скрипт, который подготавливает данные и вызывает все остальные функции. Я уже пытался выборочно комментировать его части, пока ошибка не исчезла, но она снова появилась, когда я переместил код на сервер с реальными данными... - person lib; 06.02.2015
comment
Да, на самом деле я ввел эту ошибку, пытаясь компенсировать другую ошибку. min была перезаписана другой функцией, которая принимает только один аргумент, поэтому в какой-то момент я вставил свой код: try: c=min(a,b) кроме: min = __builtins__['min'] . Так что исходный баг остался, но этот вопрос закрыт! - person lib; 06.02.2015

Вы можете удалить его, но вам придется сделать это явно:

>>> min(5,5)
5
>>> del __builtins__.min
>>> min(5,5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'min' is not defined

Простое удаление из функции не удаляет его из __builtins__, поэтому ваш вызываемый объект должен делать это намеренно.

person david king    schedule 06.02.2015
comment
извините, я пропустил формат в вопросе. На самом деле функция все еще находится в встроенных, ошибка только в одной системе, где я получаю min = __builtins__['min'] TypeError: объект 'module' не подлежит подписке - person lib; 06.02.2015