Несоответствующий объем в python - PullRequest
0 голосов
/ 28 мая 2020

Я пробовал создать такую ​​функцию:

n = ["one", "two"]
result=""
def join_strings(words):
  for word in words:
    result+=word
  return result
print (join_strings(n))

Это не работает и выводит:

UnboundLocalError: local variable 'result' referenced before assignment

Переменная результата должна быть внутри функция для его работы.

Однако, когда у меня есть эта простая функция:

x=3
def price():
  return (x+3)
print (price())

Это работает и печатает цену, даже если x составляет за пределами от функция. Почему это происходит?

Ответы [ 2 ]

2 голосов
/ 28 мая 2020

На самом деле несоответствия нет, поскольку приведенные вами примеры отличаются друг от друга. Во второй функции все равно не получится, если вы попытаетесь присвоить себе x, например:

>>> x = 3
>>> def price():
...     x +=3
...     return x
...
>>> price()
UnboundLocalError: local variable 'x' referenced before assignment

Вместо того, чтобы возвращать x, если вы выберете другое имя, он будет работать без проблема:

>>> def price():
...     y  = x + 3
...     return y
...
>>> price()
6

Но почему это происходит?

Это из-за правил области видимости Python. Вы можете прочитать значение переменной вне функции, но вы не можете изменить это **. Когда вы выполняете x += 3, что аналогично x = x + 3 для целых чисел, это означает: « У меня есть переменная x, к которой у меня есть доступ на запись в текущей области. » У вас нет есть такая переменная, поэтому, как говорится в ошибке: вы ссылаетесь на «локальную переменную» перед назначением.

Есть ли способ изменить их в функции?

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

>>> x = 3
>>> def price():
...     global x
...     x += 3
...     return x
...
>>> x
3
>>> price()
6
>>> x
6

** Под изменением , я имею в виду присвоение ему чего-то еще, чтобы он id изменение.

1 голос
/ 28 мая 2020

Разница в том, что во втором примере вы не пытаетесь изменить или переназначить x. (Вы получите ту же ошибку, если скажете что-то вроде x += 3 в функции price.) После использования оператора присваивания вы привязываете новое значение к этому имени, затеняя внешнюю область видимости.

Если вы хотите иметь возможность изменять что-то из внешней области видимости, поместите это в изменяемый контейнер (например, список); затем вы можете изменить содержимое без переназначения этой переменной.

result = [""]
def join_strings(words):
    for word in words:
        result[0] += word
    return result[0]

Если вы просто хотите иметь возможность ссылаться на значение result, не изменяя его, это тоже хорошо, но вы должны назначить его затем новую переменную:

result = ""
def join_strings(words):
    ret = result
    for word in words:
        ret += word
    return ret
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...