Что вам еще нужно?Мне стыдно признаться, но я об этом не знал. Я почему-то свято верил в то, что при присвоении объекта переменной создаётся его копия, а не ссылка на объект.
>>> 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
>>>
FerromanМарк Лутц (2009) 171-175.
Если кто-то заметил - ткните меня носом, пожалуйста.
Андрей Светлов:( Не совсем понимаю
в Питоне нет понятия 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Нет. Вначале переменная всё та же. Как только с ней производится операция 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
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