Как изменить переменную после того, как она уже определена в Python
Я пытаюсь добавить или вычесть из определенной переменной, но я не могу понять, как перезаписать старое значение новым.
a = 15
def test():
a = a +10
print ( a )
test()
Сообщение об ошибке:
Traceback (most recent call last):
File "test.py", line 7, in <module>
test()
File "test.py", line 4, in test
a = a +10
UnboundLocalError: local variable 'a' referenced before assignment
Ответы
Ответ 1
Ошибка, возникающая при попытке запустить код:
UnboundLocalError: local variable 'a' referenced before assignment
... который, на первый взгляд, кажется странным: ведь первое утверждение в коде выше (a = 15
) является назначением. Итак, что происходит?
На самом деле происходит две разные вещи, и ни одна из них не очевидна, если вы уже не знаете о них.
Прежде всего, у вас фактически есть две разные переменные:
-
a
в вашей первой строке - это глобальная переменная (так называемая, потому что она существует в глобальной области, вне любых определений функций).
-
a
в других строках - это локальная переменная, означающая, что она существует только внутри вашей функции test()
.
Эти две переменные полностью не связаны друг с другом, хотя они имеют одинаковое имя.
Переменная локальна для функции, если в ней назначается оператор, например, ваша строка a = a +10
.
Тем не менее, ошибка по-прежнему выглядит странно - в конце концов, самое первое, что вы делаете внутри test()
, присваивается a
, поэтому как это можно сделать заранее?
Ответ заключается в том, что в инструкции присваивания Python оценивает все в правой части знака =
, прежде чем назначать его имени с левой стороны - так что даже если назначение записывается сначала в вашем коде, a
сначала ссылается на правую сторону: a +10
.
Есть два способа обойти это. Во-первых, чтобы сказать Python, что вы действительно хотите, чтобы a
внутри test()
был тем же самым a
в глобальной области:
def test():
global a
a = a + 10
print(a)
Это будет работать, но это довольно плохой способ писать программы. Изменение глобальных переменных внутри функций затрудняет управление очень быстро, потому что у вас обычно есть много функций, и никто из них никогда не может быть уверен, что другой не возится с глобальной переменной, каким-то образом они не ожидают.
Лучше всего передать переменные в качестве аргументов в функции, например:
a = 15
def test(x):
x = x + 10
print(x)
test(a)
Обратите внимание, что имя не должно быть одинаковым - ваше новое определение test()
просто говорит, что оно принимает значение, а затем что-то делает с ним. Вы можете передать все, что захотите - это может быть a
, или число 7
, или что-то еще. Фактически, ваш код всегда будет легче понять, если вы попытаетесь избежать наличия переменных с тем же именем в разных областях.
Если вы играете с кодом выше, вы заметите что-то интересное:
>>> a = 15
>>> test(a)
25
>>> a
15
... a
не изменилось! Это потому, что, хотя вы передали его в test()
и присвоили его x
, тогда было изменено x
, оставив только оригинальный a
.
Если вы хотите действительно изменить a
, вам нужно вернуть измененный x
из функции, а затем переназначить его обратно на a
снаружи:
>>> a = 15
>>>
>>> def test(x):
... x = x + 10
... print(x)
... return x
...
>>> a = test(a)
25
>>> a
25
Ответ 2
Я бы сделал это следующим образом:
def test(a):
a = a +10
return a
print(test(15))
Обратите внимание, что в предложенной версии есть некоторые вещи, отличающиеся от ваших.
Во-первых, то, что я записал, создаст функцию, которая в качестве входного значения будет иметь значение a (в этом случае значение 15, когда мы вызываем функцию, уже определенную в последней строке,), затем присваивает объекту a значение a (которому было 15) плюс 10, а затем возвращает a (который был изменен и теперь 25) и, наконец, выводит a из-за последней строки кода:
print(test(15))
Обратите внимание, что то, что вы сделали, на самом деле не было чистой функцией. Обычно мы хотим, чтобы функции получали входное значение (или несколько) и возвращали входное значение (или несколько). В вашем случае у вас было введенное значение, которое было фактически пустым и не имело выходного значения (поскольку вы не использовали return). Кроме того, вы пытались записать этот вход a вне функции (который, когда вы вызвали его, произнеся test(a)
, значение a не было загружено, дало вам ошибку - т.е. в глазах компьютера он был "пустым" ).
Кроме того, я бы посоветовал вам привыкнуть к написанию return внутри функции, а затем использовать печать при ее вызове (так же, как я написал в последней строке кодирования: print(test(15))
) вместо использования его внутри функции. Лучше использовать печать только тогда, когда вы вызываете функцию и хотите увидеть, что делает функция на самом деле.
По крайней мере, так они показали мне основные уроки программирования. Это может быть оправдано следующим образом: если вы используете возврат внутри функции, функция даст вам значение, которое впоследствии может использоваться в других функциях (т.е. функция возвращает то, с чем вы можете работать с). В противном случае вы получите только номер, отображаемый на экране с печать, но компьютер не смог бы работать с ним.
P.S. Вы можете сделать то же самое:
def test(a):
a +=10
return a
print(test(15))
Ответ 3
Вы изменяете переменную a
, созданную в области функции test()
. Если вы хотите изменить внешний тэг a
, вы можете сделать:
a = 15
def test():
global a
a = a + 1
print(a)
test()
Ответ 4
# All the mumbo jumbo aside, here is an experiment
# to illustrate why this is something useful
# in the language of Python:
a = 15 # This could be read-only, should check docs
def test_1():
b = a + 10 # It is perfectly ok to use 'a'
print(b)
def test_2():
a = a + 10 # Refrain from attempting to change 'a'
print(a)
test_1() # No error
test_2() # UnboundLocalError: ...
Ответ 5
Ваша ошибка не имеет отношения к уже определенному...
Переменная действительна только внутри нее так называемой области видимости: если вы создаете переменную в функции, она определяется только в этой функции.
def test():
x=17
print(x) # returns 17
test()
print(x) # results in an error.