2015-01-30 2 views
4

Я пытаюсь уточнить для себя правила Python для присвоения значений переменным.Понимание связывания имени python

Является ли следующее сравнение между Python и C++ действительным?

  1. В C/C++ в заявлении int a=7 средства, память выделяется для целой переменной называется a (количество на ЛЕВЫЙ от = знака) и только тогда значение 7 хранится в нем.

  2. В Python заявление, a=7 средство, безымянного целое число со значением объекта 7 (количество на ПРАВЫЙ стороне =) сначала создается и хранится где-то в памяти. Затем к этому объекту привязано имя a.

Вывод следующих программ на C++ и Python, похоже, подтверждает это, но я хотел бы получить некоторые отзывы о том, прав я.

C++ производит различные ячейки памяти для a и b то время как a и b, кажется, относятся к тому же место в Python (идущий на выходе идентификатора функции())

C код

#include<iostream> 
using namespace std; 
int main(void) 
{ 
    int a = 7; 
    int b = a; 
    cout << &a << " " << &b << endl; // a and b point to different locations in memory 
    return 0; 
} 
++

Выход: 0x7ffff843ecb8 0x7ffff843ecbc

Python: код

a = 7 
b = a 
print id(a), ' ' , id(b) # a and b seem to refer to the same location 

Выход: 23093448 23093448

+2

Вы могли бы найти это полезным: [Факты и мифы о Имена и значения Python] (http://nedbatchelder.com/text/names.html). – unutbu

+0

@unutbu Это потрясающая ссылка. Большое спасибо! – smilingbuddha

ответ

5

Да, вы в основном правильно. В Python имя переменной можно рассматривать как ссылку на значение (не в терминах ссылки на C++, хотя это работает аналогично, более справедливое утверждение, что оно относится к чему-то).

Как и в сторону, то, как Python, очень похож на С ++ int &b = a, который просто означает a и b относятся к тому же значению.

Или C int *pb = &a, что означает a и *pb относятся к тому же значению, но со всей путаницы, которая приносит людям, которые еще не приняли мозг-bendedness из C :-)

Присвоение имени переменного в Python делает имя относится к различному значения, оно никогда не копирует само значение:

a = 7 # Create "7", make "a" refer to it. 
b = a # make "b" refer to the "7" as well. 
a = 42 # Create "42", make "a" refer to it, b still refers to the "7". 

(я говорю «создать», но это не обязательно так - если значение ALRE ady существует где-то, он может повторно использовать его).

В C-подобном языке, что второе утверждение b = a создает новое значение в копирует «7» в него, а затем имена, b. В Python он просто заканчивается a и b, ссылаясь на то же значение.

Если базовые данные неизменяемы (не могут быть изменены), это обычно делает Python похожим на то, что он ведет себя одинаково с тем, как это делает C.

Но для изменяемых данных (так же, как с помощью указателей в C или ссылки на C++), люди иногда могут быть удивлены, потому что они не понимают, что значение за ним могут быть разделены:

>>> a = [1,2,3] ; print a 
[1, 2, 3] 

>>> b = a ; print b 
[1, 2, 3] 

>>> a[1] = 42 ; print a 
[1, 42, 3] 

>>> print b #WTH? 
[1, 42, 3] 

Есть способы, чтобы получить независимые копии значения, с вещами, такими как:

b = a[:] 
b = [item for item in a] 

(который будет работать на одном уровне, где b = a работает на нулевые уровни) или используя deepcopy, если вы хотите, если полностью уникальный, на любой уровень необходим.

+0

У меня смешанные чувства об объяснении имен Python с точки зрения указателей. Конечно, это может быть полезно людям, которые уже понимают указатели, но также поощряет их переводить концепции Python в их привычный образ жизни в старой школе, а не охватывать Путь Python. Поэтому я предпочитаю говорить, что назначение Python в конечном итоге является операцией словаря: объект помещается в словарь с именем в качестве ключа. И из языка, используемого в вопросе, кажется, что smilebuddha уже получает это. :) –

+0

@ PM2Ring, изменил его на использование «ссылается», надеюсь, что это сделает его менее вероятным для блокировки определенной концепции языка. – paxdiablo

+0

Не беспокойтесь, pax. Но эй, это твой зов, я не претендую на то, чтобы быть прекрасным учителем Питона. :) Ответы здесь должны быть вневременными, но я считаю, что в целом проще объяснить подобные вещи интерактивным способом, корректируя объяснение, пока не найду что-то, что нажимает на читателя/слушателя. –

0

В вашем примере кода, поскольку «int» является встроенным типом в C++, поэтому оператор «=» не может быть перегружен, но «=» не всегда создает новый объект, он также может ссылаться на тот же объект. Объектный модуль python похож на Java, большая часть объекта является ссылкой, но не копией.

Вы также можете попробовать это:

a = 7 
b = 7 
print id(a), ' ' , id(b) 

это выход тот же результат, как и питона найти А и Б указывают на то же константной переменной