Mi a sekély és mély másolás?

Olykor szükségünk lehet objektumok másolatának előállítására. Ez elsőre talán nem tűnik túl izgalmas dolognak. Azonban, ha összetett objektumokról van szó, akkor már vetődnek fel kérdések. Összetett objektumnak tekintjük azt, amely más objektumokat tartalmaz, más szóval rendelkezik azok referenciájával. Ebben az esetben az a kérdés merül fel, hogy a másolás csak a tartalmazó objektumot érinti, vagy az összetevőket is.

A sekély másolásról (shallow copy) akkor beszélünk, ha legfeljebb csak a tartalmazó objektum másolata lesz új objektum, de a komponens objektumok nem, azoknak csak a referenciája másolódik. Ha azonban mind a tartalmazó objektumok, mind a komponens objektumok eltérő azonossággal rendelkeznek egy összetett objektum és annak másolata tekintetében, akkor mély másolásról (deep copy) van szó.

A szabványos könyvtár copy moduljának copy() függvényével az argumentumként megadott objektum sekély másolatát tudjuk előállítani, a deepcopy() függvénnyel pedig a mély másolást végezhetjük el.

Az alábbi képen a sekély és mély másolás koncepcionális különbségét illusztráltuk vizuálisan.

A következő programkódban pedig nyomon követhetjük egy példán a kettő közötti eltérést. Két összetett objektumot másoltunk, egy változtatható konténert, amely jelen esetben egy lista, valamint egy egyszerű, egyénileg definiált osztály példányát.

Először létrehozzuk a sekély és mély másolatokat. Ezeket megjelenítettük. Azután lista esetében az eredeti első elemének tartalmát átírtuk, az osztálypéldány esetében az eredeti példány attribútuma értékobjektumát módosítottuk. A változtatások utáni állapotot szintén kiírtuk. Láthatjuk, hogy a módosítások hatása minkét esetben a sekély másolatokban is jelentkezik, a mély másolatokban azonban nem, hiszen ilyenkor az eredetitől teljesen független másolatról van szó.

A témáról kicsit részletesebben a Python tudásépítés lépésről lépésre című e-könyv „Összetett objektumok másolása” fejezetben olvashatunk, ahol arról is szó van, hogy egy általunk definiált osztályhoz a másolást hogyan tehetjük egyedivé, amire akkor lehet szükség, ha a copy() vagy deepcopy() hívásakor nem minden attribútumot kívánunk másolni.

Érdekel a Python tudásépítés lépésről lépésre az alapoktól az első asztali alkalmazásig című e-könyv.