Как изменить переменную после того, как она уже определена в 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.