2015-01-06 3 views
4

Может ли кто-нибудь объяснить следующий результат в Python?Ссылка на глобальные примитивы и объекты

При выполнении следующего фрагмента кода, Python выдает ошибку, говоря, что переменная x сослались перед тем назначение:

x = 1 

def increase_x(): 
    x += 1 

increase_x() 

Решение, конечно, будет включать линию global x после функции декларация для increase_x.

Однако при выполнении этого следующий фрагмент кода, нет никакой ошибки, и результат того, что вы ожидаете:

x = [2, -1, 4] 

def increase_x_elements(): 
    for k in range(len(x)): 
     x[k] += 1 

increase_x_elements() 

Это потому, что целые примитивы в Python (а не объектов) и так x в первом фрагменте есть примитив, хранящийся в памяти, а x во втором фрагменте ссылки на указатель на объект списка?

+3

* Все в Python - это объект *, даже целые числа. Разница заключается в том, что один из них изменен (список), а один является неизменным (целое число). – Ffisegydd

+1

Этот вопрос объясняет причину этого. http://stackoverflow.com/questions/21456739/unboundlocalerror-local-variable-l-referenced-before-assignment-python http://stackoverflow.com/questions/9264763/unboundlocalerror-in-python – doptimusprime

ответ

3

Как указывает Ffisegydd, в Python нет такой вещи, как примитив: все это объект.

Следует отметить, что вы делаете две совершенно разные вещи в этих двух фрагментах. Во-первых, вы перетаскиваете x на значение x + 1. Пытаясь назначить x, вы сделали его локально ограниченным, поэтому ваша ссылка на x + 1 терпит неудачу.

Во втором фрагменте вы изменяете содержимое х, а не перекручиваете его. Это работает, потому что списки изменяемы, но разница не изменена и неизменна, но мутирует и перевязывает: переупорядочение изменчивого объекта завершится неудачно, как это делает целое число.

+0

Это почему я не пытался на самом деле ответить, потому что 1) у меня не было кофе и 2) я не был уверен, как полностью объяснить это/был ли я абсолютно прав: P – Ffisegydd

Смежные вопросы