Найти - Пользователи
Полная версия: Копирование объектов класса и deepcopy
Начало » Python для новичков » Копирование объектов класса и deepcopy
1 2
Nolr
Добрый день.
Объясните, пожалуйста, почему при выходе из метода find в self оказывается атрибуты bar, а не foo?
class baz:
a = 1

def calc(self, value):
self.a = value
return copy.deepcopy(self)

def find(self):
foo = self.calc(1)
bar = self.calc(2)

self = copy.deepcopy(foo) # в self будет объект с a == 1
print self.a


x = baz()
print x.a

x.find()
print x.a # но тут a == 2
Можно обойти это так:
...
return foo

x = baz()
print x.a

y = x.find()
print x.a # но тут a == 2
print y.a
Но мне это кажется некрасивым решением.
py.user.next
потому что self - локальная переменная метода
Nolr
А как изменить атрибуты экземпляра объекта baz, кроме явного копирования каждого из атрибутов объектов?
Есть ли ещё способы как можно вернуть из функции все атрибуты объекта, без описания каждого из атрибутов в return, и записать их в другой экземпляр объекта?

Вообще, мне не слишком понятен Ваш ответ. С помощью self я могу ссылаться на экземпляр класса. Так ведь? Но вот почему в объект x не копируется содержимое объекта foo? До копирования у объекта x и self в функции find() одинаковые адреса, а после копирования self перестёт ссылаться на x. Объясните свой ответ другими словами, пожалуйста.
py.user.next
Nolr
С помощью self я могу ссылаться на экземпляр класса.
self - это локальная переменная
когда метод вызывается, ей присваивается то, что в него передаётся (метод вызывается у экземпляра, он себя сам передаёт в свой метод)
когда делаешь внутри метода self = value, локальная переменная теряет своё прежнее значение и получает новое
если раньше там был экземпляр, то можно было через self обращаться к его свойствам и методам
а когда там стало value, то теперь там value, можешь через self обращаться к свойствам и методам value
py.user.next
>>> class A:
... def m(self):
... self.a = 1
... self = None
... print(self)
...
>>> obj = A()
>>> obj.m()
None
>>> obj.a
1
>>>
Nolr
Ага, теперь понятно почему self = copy.deepcopy(foo) создает новый объект. Мой промах, забыл о динамической типизации, хотел работать как с указателем. Спасибо за разъяснения.

А вот такой код хорош для копирования атрибутов экземпляра класса? Меня смущают объявления внутри класса на самого себя - foo = baz().
class baz:
def __init__(self):
self.a = 1
self.b = [2, 3]

def calc(self, value):
self.a = value
self.b[0] = value
return self.__dict__


def find(self):
foo = baz()
bar = baz()

foo = foo.calc(7)
bar = bar.calc(8)
self.__dict__ = foo
pass

x = baz()

x.find()
print x.a, x.b
Fibio
Как-то Вы совсем все запутали, self.__dict__ = foo - это вобще очень не тру, какова изначально задача? что должно происходить когда вызывается x.find()?
Nolr
calc() производит обработку атрибутов переданного экземпляра.
find() вызывает calc() с разными параметрами и ищет по заданным критериям результат. Грубо говоря, в find() вызывается calc() с параметрами от 1 до 10 и ищется минимальное значение результата вычислений. В переменной для хранения минимума нужно хранить все атрибуты объекта.

class baz:
def __init__(self):
self.a = 1
self.b = [2, 3]

def calc(self, value):
self.a = value
self.b[0] = value
return self.a + self.b[0]

def find(self):
min = calc(1)
i = 1
while i <= 10:
foo = calc(i)
if min > foo:
min = foo
i += 1
# а тут нужно в экземпляр объекта записать минимум
pass

x = baz()

x.find()
Fibio
# -*- coding: utf-8 -*-
class baz(object):
def __init__(self, a=1, b=[2, 3]):
self.a = a
self.b = b

def calc(self, value):
self.a = value #не пойму зачем calc переопределяет атрибуты?
self.b[0] = value
return self.a + self.b[0]

def find(self):
min = self.calc(1)
for i in range(2,10):
foo = self.calc(i)
if min > foo:
min = foo
self.res = min
return self.res
#в экземпляр объекта неозможно записать число, м.б. присвоить атрибуту объекта?
#и возвращать при использовании принт:

def __repr__(self):
try:
return str(self.res)
except AttributeError:
return str(super(baz, self).__repr__())

if __name__ == '__main__':
x = baz()
print x
x.find()
print x
Nolr
# -*- coding: utf-8 -*-
class baz(object):
def __init__(self, a=1, b=[2, 3]):
self.a = a
self.b = b
# на деле тут около 20 атрибутов

def calc(self, value):
self.a = value # этими выражениями я заменил длинные расчеты, производимые с атрибутами объекта
self.b[0] = value
return self.a + self.b[0] # я бы хотел, что бы тут возвращался некий объект, в котором будет
# храниться a, b и куча других атрибутов, в том числе и минимум.

# функция ищет нужный минимум, а потом дальше будет идти другая обработка с этим минимумом и
# атрибутами, которые этот минимум образовывают
# Т.е. мне нужен не только сам результат, но и все атрибуты, которые учавствовали в вычислении результата
# Можно хранить номер итерации, при которой был получен минимум, и потом произвести эти вычисления
# заново, но я решил: а почему бы не хранить все нужное в объекте
def find(self):
min = self.calc(1) #
for i in range(2,10):
foo = self.calc(i)
if min > foo:
min = foo
self.res = min
return self.res
...
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