Уведомления

Группа в Telegram: @pythonsu

#1 Март 1, 2010 16:54:39

Dimka665
От:
Зарегистрирован: 2008-09-19
Сообщения: 177
Репутация: +  0  -
Профиль   Отправить e-mail  

Ссылка на объект

не о том подумал. имел ввиду hash().



Офлайн

#2 Март 1, 2010 19:46:07

Ferroman
От:
Зарегистрирован: 2006-11-16
Сообщения: 2759
Репутация: +  1  -
Профиль   Отправить e-mail  

Ссылка на объект

Что вам еще нужно?
Мне стыдно признаться, но я об этом не знал. Я почему-то свято верил в то, что при присвоении объекта переменной создаётся его копия, а не ссылка на объект.

Может быть (скорее всего), я плохо читал документацию, но я нигде не вижу, что об этом написано прямо. Если кто-то заметил - ткните меня носом, пожалуйста. А то я про контейнеры ссылок (tuples, lists, dictionaries) вижу, а про объекты - нет.
Или я чего-то не понимаю?

Кстати, иллюстрация того, чего я не знал. Может я не один такой тупой.
>>> class A:
... def f(self,x):
... self.x = x
...
>>> d = A()
>>> b = d
>>> b is d
True
>>> b.f(10)
>>> d.x
10
>>> def sm(x):
... x.x = 102
...
>>> d.x
10
>>> sm(d)
>>> d.x
102
>>> b.x
102
>>>

Офлайн

#3 Март 1, 2010 20:44:31

knkd
От:
Зарегистрирован: 2009-06-14
Сообщения: 225
Репутация: +  0  -
Профиль   Отправить e-mail  

Ссылка на объект

Ferroman
Если кто-то заметил - ткните меня носом, пожалуйста.
Марк Лутц (2009) 171-175.
Там в том смысле пишется что все изменяемые объекты передаются по ссылке, но подразумевается что некоторые объекты (неизменяемые) могут передаваться и по значению. В каких именно случаях я так и не понял. Про именно классы упоминается вскользь.
С этим почему то во всей документации большая путаница.
То ли дело в Яве - простые типы по значению, составные по ссылке. Шаг влево, шаг вправо - расстрел.



Офлайн

#4 Март 1, 2010 22:45:17

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Ссылка на объект

Ferroman, b и d - один и тот же объект. Где именно об этом пишется в документации - не знаю. Разве что Python C API очень явно показывает ссылочную модель Питона :)

knkd, в Питоне нет понятия boxing - т.е. все (вообще все) объекты передаются и хранятся исключительно по ссылке. По значению ничто не передается никогда. Неизменяемые типы создают новый экземпляр при операциях над ними.
>>> a = 1.1
>>> b = 2.2
>>> c = a + b
>>> id(a), id(b), id©
(20920144, 25463512, 25463488)



Офлайн

#5 Март 1, 2010 23:41:34

ZZZ
От: Москва
Зарегистрирован: 2008-04-03
Сообщения: 2161
Репутация: +  26  -
Профиль   Адрес электронной почты  

Ссылка на объект

Хм… А я всегда думал, что это она из важнейших парадигм питона…



Офлайн

#6 Март 1, 2010 23:48:27

knkd
От:
Зарегистрирован: 2009-06-14
Сообщения: 225
Репутация: +  0  -
Профиль   Отправить e-mail  

Ссылка на объект

Андрей Светлов
в Питоне нет понятия boxing - т.е. все (вообще все) объекты передаются и хранятся исключительно по ссылке.
:( Не совсем понимаю
In [36]: a=1

In [37]: def f(x):
....: x+=1

In [38]: f(a)
In [39]: a
Out[39]: 1
С виду поведение аналогичное передаче простого типа по значению.
Можете объяснить подробнее в чём разница?
In [40]: class A:
....: a=1

In [41]: def F(X):
....: X.a += 1

In [42]: a=A()

In [43]: a.a
Out[43]: 1

In [44]: F(a)

In [46]: a.a
Out[46]: 2
Поведение с виду аналогичное передаче сложного типа по ссылке…



Отредактировано (Март 1, 2010 23:49:08)

Офлайн

#7 Март 2, 2010 00:06:52

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Ссылка на объект

Пошел ликбез:

a = 1 # globals['a'] = 1
def f(x):
x += 1
# для классического int это аналогично locals['x'] = locals['x'] + 1
# т.е. локальное имя указывает на новый объект. Старый - не трогается
# но на самом деле это вызов метода __iadd__ у левого аргумента - и ничего больше
# locals['x'] = locals['x'].__iadd__(1)

f(a) # a - не поменяли.
assert a==1

class BadInt(object):
def __init__(self, v):
self.v = v
def __iadd__(self, other):
self.v += int(other)
return self
def __repr__(self):
return self.v

b = BadInt(1)
f(b)
assert b.v == 2

class GoodInt(Int):
def __iadd__(self, other):
return GoodInt(self.v + int(other))

c = Int(1)
f(c)
assert c.v == 1



Отредактировано (Март 2, 2010 00:10:25)

Офлайн

#8 Март 2, 2010 00:25:20

knkd
От:
Зарегистрирован: 2009-06-14
Сообщения: 225
Репутация: +  0  -
Профиль   Отправить e-mail  

Ссылка на объект

Андрей Светлов
# т.е. локальное имя указывает на новый объект. Старый - не трогается
Разве это не то же самое что передача по значению? Внутри функции ведь появляется копия объекта на который указывала внешняя переменная. Которая полностью независима от внешнего (и наоборорт)



Офлайн

#9 Март 2, 2010 00:32:15

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

Ссылка на объект

knkd
Разве это не то же самое что передача по значению?
Нет. Вначале переменная всё та же. Как только с ней производится операция x += 1, появляется новая локальная переменная.
>>> def foo(x):
... print id(x) # тут x - та которая внешняя
... x += 1
... print id(x) # тут уже новая
...

>>> x = 1

>>> id(x)
149301088
>>> foo(x)
149301088
149301076
>>> x
1
По сути в питоне действительно всё ссылки, но есть два типа объектов – mutable и immutable.



Офлайн

#10 Март 2, 2010 00:40:34

knkd
От:
Зарегистрирован: 2009-06-14
Сообщения: 225
Репутация: +  0  -
Профиль   Отправить e-mail  

Ссылка на объект

Daevaorn
Нет. Вначале переменная всё та же. Как только с ней производится операция x += 1, появляется новая локальная переменная.
Так окончательно понятно (с простыми).

Передача по ссылке - толь объект ссылки принципиально неизменяемый.

Даже так.
In [54]: def ff(x):
....: print id(x)
....: return x

In [55]: a=1

In [56]: id(a)
Out[56]: 31687320

In [57]: aa = ff(a)
31687320

In [58]: id(aa)
Out[58]: 31687320



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version