2015-09-28 14 views
6

Bir proxy nesnesini döndüren bir sınıfta bir çeşit tanımlayıcı oluşturmak istiyorum. Proxy nesnesi, indekslendiğinde nesnenin üyelerini alır ve dizine bunları uygular. Sonra toplamı döndürür. Şimdi (cluster_signal dönen açıklayıcısı protokolünü uygulayan Python tanımlayıcıları içine benim diziler değiştirdikPython'da uyarlanabilir tanımlayıcı

class CompartmentCluster(Cluster): 

    """ 
    Base class for cluster that manages evidence. 
    """ 

    def __init__(self, **kwargs): 
     super().__init__(**kwargs) 

     self.variable_evidence = ArraySumProxy([]) 

class BasicEvidenceTargetCluster(CompartmentCluster): 

    # This class variable creates a Python object named basic_in on the 
    # class, which implements the descriptor protocol. 

    def __init__(self, 
       *, 
       **kwargs): 
     super().__init__(**kwargs) 

     self.basic_in = np.zeros(self.size) 
     self.variable_evidence.arrays.append(self.basic_in) 

class ExplanationTargetCluster(CompartmentCluster): 

    """ 
    These clusters accept explanation evidence. 
    """ 

    def __init__(self, **kwargs): 
     super().__init__(**kwargs) 

     self.explanation_in = np.zeros(self.size) 
     self.variable_evidence.arrays.append(self.explanation_in) 

class X(BasicEvidenceTargetCluster, ExplanationTargetCluster): 
    pass 

: Ben üye değişkenler olarak fiili diziler varken

Ör

class NDArrayProxy: 

    def __array__(self, dtype=None): 
     retval = self[:] 
     if dtype is not None: 
      return retval.astype(dtype, copy=False) 
     return retval 


class ArraySumProxy(NDArrayProxy): 

    def __init__(self, arrays): 
     self.arrays = arrays 

    @property 
    def shape(self): 
     return self.arrays[0].shape 

    def __getitem__(self, indices): 
     return np.sum([a[indices] 
         for a in self.arrays], 
         axis=0) 

Bu çözüm iyi çalıştı Bir numpy dizisi):

class CompartmentCluster(Cluster): 

    """ 
    Base class for cluster that manages evidence. 
    """ 

    def __init__(self, **kwargs): 
     super().__init__(**kwargs) 

     self.variable_evidence = ArraySumProxy([]) 

class BasicEvidenceTargetCluster(CompartmentCluster): 

    # This class variable creates a Python object named basic_in on the 
    # class, which implements the descriptor protocol. 

    basic_in = cluster_signal(text="Basic (in)", 
           color='bright orange') 

    def __init__(self, 
       *, 
       **kwargs): 
     super().__init__(**kwargs) 

     self.variable_evidence.arrays.append(self.basic_in) 

class ExplanationTargetCluster(CompartmentCluster): 

    """ 
    These clusters accept explanation evidence. 
    """ 

    explanation_in = cluster_signal(text="Explanation (in)", 
            color='bright yellow') 

    def __init__(self, **kwargs): 
     super().__init__(**kwargs) 

     self.variable_evidence.arrays.append(self.explanation_in) 

class X(BasicEvidenceTargetCluster, ExplanationTargetCluster): 
    pass 

Bu işe yaramadı çünkü ek ifadeler, tanımlayıcı çağrısının sonucunu ekler. İhtiyacım olan şey bağlı bir yöntem veya benzer bir proxy eklemek. Çözümümü değiştirmenin en güzel yolu nedir? Kısaca: basic_in ve explanation_in değişkenleri numpy dizileridir. Onlar şimdi tanımlayıcılar. Gerçek dizileri gerektirmekten ziyade betimleyicilerle çalışan ArraySumProxy'un bir versiyonunu geliştirmek istiyorum.

+0

Sorunuzu tam olarak anlamadım. Bu sınıfları daha önce nasıl kullandığını ve neyin değiştiğini ve bu değişiklikten sonra bunları nasıl kullanacağınızı nasıl gösterirsiniz? – BrenBarn

+0

@brenbarn: Özetlendi. –

+1

Hangi kodun her zaman kullanımda olduğunu ve hangi kodun yeni olduğunu sorunuzdan anlayamıyorum. –

cevap

1

Bir tanıtıcıya eriştiğinizde, değerlendirilir ve yalnızca değeri alırsınız. Tanımlayıcınız her zaman aynı nesneyi döndürmediğinden (sanırım avioid edemezsiniz), proxy'nizi başlatırken tanımlayıcıya erişmek istemezsiniz. Yapmanız

self.variable_evidence.arrays.append(self.basic_in) 

:

self.variable_evidence.arrays.append((self, 'basic_in')) 

Sonra, elbette, variable_evidence farkında olmak zorundadır

basit yolu böylece yerine, sadece kendi adını hatırlamak, erişirken önlemek için Bunu yapmak ve erişmek için getattr(obj, name) yapın.

Başka bir seçenek, tanıtıcının daha sonra değerlendirilecek bir proxy nesnesini döndürmesidir. Ben ne yaptığını bilmiyorum, ama bu iyi tadı için çok fazla proxy olabilir ...

DÜZENLEME

Ya ... sen getter saklayabilirsiniz:

self.variable_evidence.arrays.append(lambda: self.basic_in) 
+2

Veya sadece 'lambda: self.basic_in'. – user2357112

+0

Ama sonra tekrar, bir tanımlayıcı alır bir alıcı olan bir vekil ... tüm bunlara ihtiyacınız var mı? – zvone

+0

@ user2357112 Evet, bu daha iyi :) – zvone

İlgili konular