Как ввести массив VALUE в качестве аргумента вместо его ССЫЛКИ? - PullRequest
0 голосов
/ 19 марта 2019

У меня небольшая проблема с питоном. Я нашел способ обойти это, но все же, это меня беспокоит ... Возьмите следующий код, где я попытался переписать проблему в ее простейшей форме:

"WE DEFINE A SIMPLE OBJET" 
class Object():
    def __init__(self,argument):
        self.table = argument

"We define an array that will be used as the argument for the 'Object' instances" 
tab = [0,0]

"We instanciate 2 'Object' using the 'tab' array as an argument" 
Obj1=Object(tab)
Obj2=Object(tab)

"We change the first value of the first Object's table to 1" 
Obj1.table[0] = 1

"RESULTS (we are expecting the first Object's tab to be [1,0] and the second to be [0,0] but we get [1,0] for both)" 
print(Obj1.table) 
print(Obj2.table)

Out:

>> [1,0]

>> [1,0]

Похоже, что вместо создания переменной self.table со значением ' tab ', self.table связана с tab переменная по ссылке. В результате, когда мы пытаемся изменить переменную self.table в одном из двух объектов, она также изменяется во всех других экземплярах. Это нормально? Что-то не так с моим кодом?

Для информации я исправил проблему, изменив 4-ю строку на:

self.table = [argument[x] for x in range(len(argument))]

Спасибо! :)

PS: я не знаю, есть ли какая-либо ссылка, но это другое поведение также вызывает у меня проблемы. Может быть, основная причина та же:

в:

a = [[0,0]]*2
a[0][0] = 1
print(a)

out:

>> [[1, 0], [1, 0]]

Это неожиданный результат, тогда как

в:

a = [[0,0] for x in range(2)]
a[0][0] = 1
print(a)

out:

>> [[1, 0], [0, 0]]

дает ожидаемый результат ..: p

Ответы [ 2 ]

0 голосов
/ 19 марта 2019

Когда вы делаете назначение, такое как в этом примере, вы создаете не новый объект, а ссылку на оригинал.Альтернатива - глубокая ксерокопия согласно https://docs.python.org/2/library/copy.html,, однако, IMO, это довольно глупо.

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

0 голосов
/ 19 марта 2019

Из документации Python:

Операторы присваивания в Python не копируют объекты, они создают привязки между целью и объектом.Для коллекций, которые являются изменяемыми или содержат изменяемые элементы, иногда требуется копия, чтобы можно было изменить одну копию без изменения другой.

Для копирования объектов существует специальный модуль, который может выполнить работу. Python копия модуль

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...