Saya ingin membuat salinan suatu objek. Saya ingin objek baru memiliki semua properti objek lama (nilai bidang). Tetapi saya ingin memiliki objek independen. Jadi, jika saya mengubah nilai bidang objek baru, objek lama seharusnya tidak terpengaruh oleh itu.
199
Maksudmu objek yang bisa berubah kemudian.
Di Python 3, daftar dapatkan
copy
metode (dalam 2, Anda akan menggunakan slice untuk membuat salinan):Salinan Dangkal
Salinan dangkal hanyalah salinan dari wadah terluar.
list.copy
adalah salinan dangkal:Anda tidak mendapatkan salinan objek interior. Mereka adalah objek yang sama - jadi ketika mereka bermutasi, perubahan muncul di kedua wadah.
Salinan dalam
Salinan dalam adalah salinan rekursif dari setiap objek interior.
Perubahan tidak tercermin dalam aslinya, hanya di salinan.
Benda yang tidak bisa berubah
Benda tidak permanen biasanya tidak perlu disalin. Bahkan, jika Anda mencoba, Python hanya akan memberi Anda objek asli:
Tuples bahkan tidak memiliki metode penyalinan, jadi mari kita coba dengan irisan:
Tapi kita lihat itu objek yang sama:
Demikian pula untuk string:
dan untuk frozenset, meskipun mereka memiliki
copy
metode:Kapan harus menyalin objek yang tidak dapat diubah
Objek yang tidak dapat diubah harus disalin jika Anda perlu menyalin objek interior yang dapat diubah.
Seperti yang dapat kita lihat, ketika objek interior dari salinan dimutasi, aslinya tidak berubah.
Objek Khusus
Objek khusus biasanya menyimpan data dalam suatu
__dict__
atribut atau dalam__slots__
(struktur memori mirip tuple).Untuk membuat objek yang dapat disalin, tentukan
__copy__
(untuk salinan dangkal) dan / atau__deepcopy__
(untuk salinan dalam).Catatan yang
deepcopy
menyimpan kamus memoisasiid(original)
(atau nomor identitas) untuk salinan. Untuk menikmati perilaku yang baik dengan struktur data rekursif, pastikan Anda belum membuat salinan, dan jika sudah, kembalikan.Jadi mari kita membuat objek:
Dan
copy
buat salinan yang dangkal:Dan
deepcopy
sekarang membuat salinan yang dalam:sumber
Salin dangkal dengan
copy.copy()
Salinan dalam dengan
copy.deepcopy()
Dokumentasi: https://docs.python.org/3/library/copy.html
Diuji pada Python 3.6.5.
sumber
Saya percaya yang berikut ini harus bekerja dengan banyak perilakunya yang baik diklasifikasikan dalam Python:
(Tentu saja, saya tidak berbicara di sini tentang "salinan dalam," yang merupakan cerita yang berbeda, dan yang mungkin bukan konsep yang sangat jelas - seberapa dalam cukup dalam?)
Menurut pengujian saya dengan Python 3, untuk objek yang tidak dapat diubah, seperti tupel atau string, ia mengembalikan objek yang sama (karena tidak perlu membuat salinan dangkal dari objek yang tidak dapat diubah), tetapi untuk daftar atau kamus ia membuat salinan dangkal independen .
Tentu saja metode ini hanya berfungsi untuk kelas yang konstruktornya berperilaku sesuai. Kasing penggunaan yang memungkinkan: membuat salinan dangkal kelas kontainer Python standar.
sumber
__init__
metode mereka . Jadi, saya pikir metode ini mungkin cukup baik untuk tujuan tertentu. Bagaimanapun, saya akan tertarik pada komentar informatif tentang saran ini.class Foo(object): def __init__(self, arg): super(Foo, self).__init__() self.arg = arg
Dasar saat mendapat. If I dofoo = Foo(3) bar = copy(foo) print(foo.arg) # 3 print(bar.arg) # <__main__.Foo object at ...>
Meaning bahwacopy
fungsi Anda rusak bahkan untuk kelas paling dasar sekalipun. Sekali lagi, ini adalah trik yang rapi (karenanya tidak ada DV), tetapi bukan jawaban.copy.copy
metode untuk membuat salinan yang dangkal, tetapi, mungkin secara naif, menurut saya seharusnya menjadi tanggung jawab kelas untuk menyediakan "konstruktor salinan yang dangkal." Dalam kasus seperti itu, mengapa tidak menyediakan antarmuka yang sama dengannyadict
danlist
melakukan? Jadi, jika kelas Anda ingin bertanggung jawab untuk menyalin objeknya, mengapa tidak menambahkanif isinstance(arg, type(self))
klausa__init__
?