Найти - Пользователи
Полная версия: Ссылка на объект
Начало » Python для новичков » Ссылка на объект
1 2 3
Dimka665
не о том подумал. имел ввиду hash().
Ferroman
Что вам еще нужно?
Мне стыдно признаться, но я об этом не знал. Я почему-то свято верил в то, что при присвоении объекта переменной создаётся его копия, а не ссылка на объект.

Может быть (скорее всего), я плохо читал документацию, но я нигде не вижу, что об этом написано прямо. Если кто-то заметил - ткните меня носом, пожалуйста. А то я про контейнеры ссылок (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
>>>
knkd
Ferroman
Если кто-то заметил - ткните меня носом, пожалуйста.
Марк Лутц (2009) 171-175.
Там в том смысле пишется что все изменяемые объекты передаются по ссылке, но подразумевается что некоторые объекты (неизменяемые) могут передаваться и по значению. В каких именно случаях я так и не понял. Про именно классы упоминается вскользь.
С этим почему то во всей документации большая путаница.
То ли дело в Яве - простые типы по значению, составные по ссылке. Шаг влево, шаг вправо - расстрел.
Андрей Светлов
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)
ZZZ
Хм… А я всегда думал, что это она из важнейших парадигм питона…
knkd
Андрей Светлов
в Питоне нет понятия 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
Поведение с виду аналогичное передаче сложного типа по ссылке…
Андрей Светлов
Пошел ликбез:
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
knkd
Андрей Светлов
# т.е. локальное имя указывает на новый объект. Старый - не трогается
Разве это не то же самое что передача по значению? Внутри функции ведь появляется копия объекта на который указывала внешняя переменная. Которая полностью независима от внешнего (и наоборорт)
Александр Кошелев
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.
knkd
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
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB