Tam Sürümünü Görmek İçin : immutable, mutable
pìsmíkrøp
17/04/2005, 20:15
Merhaba,
Benim python ile ilgili temel bir sorum var bunun mutable, immutable (değiştirilebilir, değiştirilemez) nesneler ile alakası olduğunu düşünüyorum. Ama çelişkilerim bulunuyor. Bu konuda nesne modelli programlamaya daha aşina arkadaşlardan yanıt bekliyorum.
>>> ornek_liste = range(4)
>>> print ornek_liste
[0, 1, 2, 3]
>>> for ornek in ornek_liste: ornek = 4
...
>>> print ornek_liste
[0, 1, 2, 3]
bunun çıktısı [0,1,2,3] fakat çıktısının [4,4,4,4] olması beklenirdi.
>>> ornek_liste = range(4)
>>> print id(ornek_liste[0])
135585212
>>> for ornek in ornek_liste: print(id(ornek))
...
135585212
135585200
135585188
135585176
>>>
Buradan da görüldüğü gibi ornek_liste[0] ve ornek'in
döngüdeki ilk değerlerinin göstegeleri aynı yani
shared object (paylaşılan nesne) peki buna rağmen neden ilk örnekte
[4,4,4,4] değerini alamıyoruz. Listeler normalde mutable
nesneler olarak bilinir.
simdiye kadar gordugum foreach dongulerinin hepsi script dillerinde idi
(c sharp , java5 haric)
ve hepsinin bir ortak ozelligi vardi ki
<vbscript>
for each item in collection ' item readonly olarak gelir
<jscript>
for(item in collection) //item i degistirmek olanaksiz.
ozet olarak bu davranis listeye degil de foreach dongusune ait bir davranis olmali
degistirilemeyen sey, liste degil, listeden o anda cekilen eleman.
fakat burada garip olan sey, degistiremedigin halde sol tarafa yazmaya izin vermesi.
hata vermesi gerekirdi.
aslinda bunu "deney" ile gosterebiliriz. bir global degiskenimiz olsun bir de liste donduren bir fonksiyonumuz olsun.
fonksiyon iki sey yapsin:
1- global degiskenin degerini bir arttir.
2- listeyi hazirla ve dondur.
foreach dongusunden bu fonksiyonu cagirdigimiz zaman buyuk ihtimalle global degiskenin sadece 1 kez arttigini gorecegiz. (dilden dile degisebilir tabii)
not : su anda makinamda "piton" yuklu degil. soylediklerimin tamami teoriktir.
pìsmíkrøp
18/04/2005, 18:40
php yardım dosyasında şöyle bir ifade var:
Note: Also note that foreach operates on a copy of the specified array and not the array itself. Therefore, the array pointer is not modified as with the each() construct, and changes to the array element returned are not reflected in the original array. However, the internal pointer of the original array is advanced with the processing of the array. Assuming the foreach loop runs to completion, the array's internal pointer will be at the end of the array.
Ama benim anlamadığım madem nesne kopyalanıyor. neden id'leri aynı?
bunun için bir deneme yaptım:
>>> import copy
>>> deneme = ['a', 'b', 'c']
>>> deneme_kopya = copy.copy(deneme);
>>> print deneme_kopya
['a', 'b', 'c']
>>> id(deneme[0])
-1209651808
>>> id(deneme_kopya[0])
-1209651808
evet kopyasınında id'si eşt oluyor nasıl yani dedim? o zaman birini değiştirince
biri de mi değişiyor?
>>> deneme[0] = 'd'
>>> deneme
['d', 'b', 'c']
>>> deneme_kopya
['a', 'b', 'c']
hayır değişmiyordu. Sonra tekrar inceledim.
>>> id(deneme[0])
-1209722720
>>> id(deneme_kopya[0])
-1209651808
Demekki python bir nesnenin kopyası yapıldığında değiştirilene kadar eski nesne
ile aynı adresi gösteriyormuş.
PHP manual ve python kabuğunun güzel bir sentezi ile sorunu çözmüş olduk. :)
myavuzselim
18/04/2005, 19:15
Anladigim kadariyla python da java gibi bir .. sistemi kullaniyor (bu .. yerine ne koymaliyim bilmiyorum. referans, pointer, degisken, obje, ... ?)
Java'da her degisken bir referanstir (primitif tipleri goz ardi ediyorum), ve bir objeyi gosterir. Bir degiskende bir degisiklik yaptiginda aslinda o degisikligi o degiskenin gosterdigi nesnede yapmis oluyorsun.
Fakat, degisken = abc dediginde, degiskenin gosterdigi objede bir degisiklik olmuyor. Degisken, abcnin gosterdigi nesneyi gostermeye basliyor.
Dizilerin icinde obje yok, sadece objeleri gosteren referanslar var.
Mesela getID() metodu olan bir A sinifimiz olsun. Asagidaki dizi icinde 10 tane 1..10 ID'lerine sahip elemanlar olsun.
A[] dizi = ...
Yine y diye, ID'si 50 olan bir degerimiz olsun:
A y = ...
x = dizi[5];
print(dizi[5].getID()); // 5 yazar
print(x.getID()); // 5 yazar
x = y;
print(dizi[5].getID()); // 5 yazar
print(x.getID()); // 50 yazar
Bunu ayni c++'daki pointerlar gibi dusunebilirsin. Tek farki, pointer aritmetigi yapamaman, ve de = disinda bu pointerlara yaptigin her islemi aslinda pointer'a degil de, pointer'in gosterdigi objeye yapman.
Sanirim python da ayni sekilde isliyor.
Forum Yazılımı : vBulletin v3.7.3, Copyright ©2000-2008, Jelsoft Enterprises Ltd.