2011-04-07 25 views
9

Ben
Values of instance variables of superclass persist across instances of subclass
gibi hissediyor garip bir alt sınıf numpy.ndarray sorun yaşıyorum Ama tam olarak anlamak ya benim örneğin için çalışması yapmak mümkün olmamıştır karşısında bağlıyor.numpy dizi alt sınıf unexpedly hisse örnekleri

ile okuma Slightly more realistic example - attribute added to existing array Tam olarak bunu yapmaya çalışıyorum. Bir sözlükteki birimler gibi bilgileri tutmak için bir diziye attrs özniteliği eklemek istiyorum.

import numpy 
class dmarray(numpy.ndarray): 
    def __new__(cls, input_array, attrs={}): 
     obj = numpy.asarray(input_array).view(cls) 
     obj.attrs = attrs 
     return obj 

    def __array_finalize__(self, obj): 
     # see InfoArray.__array_finalize__ for comments 
     if obj is None: 
      return 
     self.attrs = getattr(obj, 'attrs', {}) 

Öyleyse kullanmak ve konuyu ben istemiyorum

a = dmarray([1,2,3,4]) 
b = dmarray([1,2,3,4]) 
a.attrs['foo'] = 'bar' 
print(b.attrs) 
#{'foo': 'bar'} 
b.attrs is a.attrs 
# True # hmm.... 

Yani b toplayıp attrs göstermek için: Burada

ben ne var. Eğer bunu yaparsanız Annoyingly iyi çalışıyor:

from datamodel import * 
a = dmarray([1,2,3,4], attrs={'foo':'bar'}) 
b = dmarray([1,2,3,4]) 
b.attrs 
# {} 

Yani dünyada ben bunu istiyorum nasıl bu dmarray çalışması nasıl?


Düzenleme: Tamam bu nedenle bu sorunu çözmek gibi görünüyor ama neden anlamıyorum. Öyleyse soruyu, bunun ne yaptığını ve neden işe yaradığını değiştirelim.

class dmarray(numpy.ndarray): 
    def __new__(cls, input_array, attrs=None): 
     obj = numpy.asarray(input_array).view(cls) 
     return obj 

    def __init__(self, input_array, attrs=None): 
     if attrs == None: 
      attrs = {} 
     self.attrs = attrs 

Yani __new__() gelen kwarg çıkarıp çalıştığını __init__() koyarak.

def __new__(cls, input_array, attrs={}) 

Fonksiyon başlığında bu attrs={} yapmak asla: Sadece

a = dmarray([1,2,3,4]) 
b = dmarray([1,2,3,4]) 
a.attrs['foo'] = 'bar' 
b.attrs 
# {} 
+0

Bir meslektaşım o hmm ben orada başka ne kullanabilirsiniz vatka() muhtemelen sorunu düşünce bunu söyledi? –

+2

Biraz da bu önemli uyarı gibi görünüyor (http://docs.python.org/tutorial/controlflow.html#default-argument-values). – lafras

+0

Teşekkürler, Sorun kesinlikle attrs = {} ama beklemediğim bir şekilde kendini gösterdi ve .copy() –

cevap

16

sorun burada "iyi işe yarayabilir" olarak çalıştı. Beklenen sonuç (muhtemelen) düşündüğünüz gibi değil. Bu yaygın bir Python Tuzağı. Burada Default Parameter Values in Python

Bunun nasıl doğru yolu bakınız:

def __new__(cls, input_array, attrs=None): 
    if attrs is None: 
     attrs = {} 
+0

'a bakmaya devam ettim. Doğru, bu cevap. Geçmişte .copy() 'ye bakın ve varsayılanı kullandığım şekilde kullanmayın. Teşekkürler. –

+0

Ya da şuna benzer: 'attrs = attrs or {}' – devxoul

+0

@devxoul - harika bir fikir, ama bu benim için özellikle güvenli görünmüyor. Python'da bir çok şey 'False' olarak kabul edilir, değil mi? Bu yapıya güvenmeyeceğim. – Fenikso

İlgili konular