SORU
27 ŞUBAT 2010, CUMARTESİ


Neden = listeler beklenmedik bir hareket yok?

Python = operatör beklenmedik bir şekilde listeler üzerinde çalışma gibi görünüyor. Herkes burada neler olduğunu söyleyebilir mi?

class foo:  
     bar = []
     def __init__(self,x):
         self.bar  = [x]


class foo2:
     bar = []
     def __init__(self,x):
          self.bar = self.bar   [x]

f = foo(1)
g = foo(2)
print f.bar
print g.bar 

f.bar  = [3]
print f.bar
print g.bar

f.bar = f.bar   [4]
print f.bar
print g.bar

f = foo2(1)
g = foo2(2)
print f.bar 
print g.bar 

ÇIKTI

[1, 2]
[1, 2]
[1, 2, 3]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3]
[1]
[2]

foo = bar foo = foo bar şeyler davranmasını beklediğiniz şekilde davranır gibi görünüyor, Oysa bu sınıfın her örneği etkileyecek gibi görünüyor.

= operatör denir "bileşik atama operatörü".

CEVAP
27 ŞUBAT 2010, CUMARTESİ


Genel cevap = __iadd__ özel yöntemini çağırmak için çalışır ve eğer mevcut değil ise bile __add__ yerine kullanmaya çalışır. Sorun bu özel yöntemler arasında.

__iadd__ özel yöntemi yerinde için ayrıca, bu hareket bir nesne mutasyona uğrar. __add__ özel bir yöntemi yeni bir nesne döndürür ve ayrıca standart operatör kullanılır.

= operatör olan bir nesnede kullanıldığında __iadd__ nesnenin yeri değiştirilmiş tanımlanır. Aksi takdirde düz __add__ kullanın ve yeni bir nesneyi döndürmek için çalışacağız yerine.

Bunun neden böyle olduğuna dair değişken türleri gibi listeler = değişiklikler nesnenin değerini, oysa için değişmez türleri gibi dizilerini, dizeleri ve tamsayılar yeni bir nesne döndürülür yerine (a = b olur eşdeğer a = a b).

__iadd__ __add__ hem destekleyen türler için bu nedenle kullandığınız dikkatli olmak zorunda. a = b __iadd__ arayıp a = a b yeni bir nesne oluşturur, oysa a, mutasyon ve a atayacaktır. Aynı işlemi değildir!

>>> a1 = a2 = [1, 2]
>>> b1 = b2 = [1, 2]
>>> a1  = [3]          # Uses __iadd__, modifies a1 in-place
>>> b1 = b1   [3]      # Uses __add__, creates new list, assigns it to b1
>>> a2
[1, 2, 3]              # a1 and a2 are still the same list
>>> b2
[1, 2]                 # whereas only b1 was changed

Değişmez tipleri __iadd__ yok () a = b a = a b eşdeğerdir. Bu size başka numaralar gibi değişmez tipleri = kullanamadın bunu düşünecek kadar garip bir tasarım kararı gözükebilir değişmez türleri, = kullanım sağlar!

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • boburnham

    boburnham

    11 Temmuz 2006
  • Doc Adams

    Doc Adams

    20 HAZİRAN 2007
  • MaximumPCMag

    MaximumPCMag

    23 Temmuz 2010