klonowanie obiektu

klonowanie obiektu
MA
  • Rejestracja:ponad 9 lat
  • Ostatnio:prawie 5 lat
  • Postów:68
0

Cześć,
Potrzebuje sklonować dany obiekt x razy.

Kopiuj
def klonowanie(self, obiekt, j):
    for i in range(1, j+1):
        klon_obiektu = copy.deepcopy(obiekt)
        print(i, "obiekt sklonowany")
    return klon_obiektu

a = klasaA()
klonowanie(a, 5)

O ile przy robieniu jednego klonu nie miałem wątpliwości to przy robieniu kilku mam wątpliwości czy robię to dobrze. Prośba o pomoc. Z góry dzięki za pomoc.

Guaz
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 4 lata
  • Lokalizacja:Częstochowa
  • Postów:221
4

Zapoznaj się z yield. Bo obecnie zakładając że sklonujesz obiekt 5-ciokrotnie. To nadal uzyskasz tylko ostatnią jego kopię w return.

Kopiuj
def klonowanie(self, obiekt, j):
    for i in range(1, j+1):
        yield copy.deepcopy(obiekt)
        
a = klasaA()
for obj in klonowanie(a, 5):
    print(obj) 

W ten sposób dostaniesz wszystkie klony po kolei w pętli for.
Bo po co robić tyle klonów, skoro ich nie wykorzystujesz w żaden sposób, ponadto po nadpisaniu adresu do zmiennej i która będzie wskazywać na nowy obiekt, stary do którego nie ma już żadnych odwołań, albo przestanie istnieć przy kolejnej iteracji, albo w ostateczności zajmie się nim garbage collector po wyjściu z funkcji.
W ten sposób możesz te obiekty dodać choćby do jakiejś listy, na przykład tak:

Kopiuj
objects = [ obj for obj in klonowanie(a, 5) ]

Linux Mint
Arduino / Python 3.5.2
  • Rejestracja:około 6 lat
  • Ostatnio:ponad rok
5
Kopiuj
>>> import collections, copy

>>> def clone_slow(obj, k=1):
...     for _ in range(k):
...         yield copy.deepcopy(obj)

>>> def clone_fast(obj, k=1):
...     deepcopy = copy.deepcopy
...     memo = {}
...     for _ in range(k):
...         yield deepcopy(obj, memo)

>>> def consume(it):
...     collections.deque(it, maxlen=0)

>>> d = {i: list(range(i)) for i in range(100)}

>>> %timeit consume(clone_slow(d, 100))
477 ms ± 2.84 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

>>> %timeit consume(clone_fast(d, 100))
4.83 ms ± 31.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

>>> 
edytowany 1x, ostatnio: Mózg
Guaz
Nie sądziłem że można to aż tak przyspieszyć, dobre do zapamiętania :D. Muszę jeszcze zerknąć jakie znaczenie ma ten drugi argument :)
@Guaz: Zwykła memoizacja – copy.deepcopy jest funkcją rekurencyjną. Zachęcam do zapoznanie się z implementacją: https://github.com/python/cpython/blob/3.7/Lib/copy.py
cmd
  • Rejestracja:około 10 lat
  • Ostatnio:dzień
  • Lokalizacja:Warszawa
  • Postów:443
0
AH
  • Rejestracja:około 6 lat
  • Ostatnio:4 minuty
  • Postów:13
0

Na jakiej zasadzie ta linijka działa?

Mózg napisał(a):
Kopiuj
>>> %timeit consume(clone_slow(d, 100))
477 ms ± 2.84 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Nie mogę tego w REPLu odtworzyć

  • Rejestracja:około 6 lat
  • Ostatnio:ponad rok
2
edytowany 1x, ostatnio: Mózg

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.