SORU
25 AĞUSTOS 2009, Salı


Nasıl python sınıf bir dinamik olarak özellik eklemek için?

Hedef db seviyesinde bağımsız gibi davranan sahte bir sınıf oluşturmaktır.

Eğer bir veritabanı sorgusu, dict bir ifade kullanarak döndürür yani, örneğin, {': 100,''cd:200'}, o zaman görmek isterdim . ab

>>> dummy.ab
100

Yani, ben başlarda bu şekilde yapmak belki mümkün düşündüm

ks = ['ab', 'cd']
vs = [12, 34]
class C(dict):
    def __init__(self, ks, vs):
        for i, k in enumerate(ks):
                self[k] = vs[i]
                setattr(self, k, property(lambda x: vs[i], self.fn_readyonly))

    def fn_readonly(self, v)
        raise "It is ready only"

if __name__ == "__main__":
    c = C(ks, vs)
    print c.ab

"c.ama ab" özelliği yerine nesnenin değerini döndürür.

İle setattr satırı değiştirin

k = property(lambda x: vs[i])

Pek bilinen bir şey.

Çalışma zamanı örnek bir özellik oluşturmak için doğru yolu nedir?

P. S. bir alternatif farkındayım here

CEVAP
31 AĞUSTOS 2009, PAZARTESİ


Daha yaşlı ve bilgili olduğumu ve neler olduğunu şimdi bu cevap genişletin etmeliyim. Hiç olmamasından daha iyi.

Sanaolabilirsınıf dinamik bir özellik ekleyin. Ama işin sırrı bu: eklemek içinsınıf.

>>> class Foo(object):
...     pass
... 
>>> foo = Foo()
>>> foo.a = 3
>>> Foo.b = property(lambda self: self.a   1)
>>> foo.b
4

property aslında bir şey descriptor denilen basit bir uygulama. Özel belirli bir öznitelik için kullanım sağlayan bir nesnebelirli bir sınıf. __getattribute__ if kocaman bir ağaç faktör için bir yol gibi.

Yukarıdaki örnekte foo.b istediğim zaman, Python b sınıfı tanımlanmış uygulayan görürtanımlayıcı protokolü—sadece ** 16*,* 15 __delete__ yöntemi ile bir nesne olduğunu gösteriyor. Tanımlayıcı aramaları için geri öznitelik değeri olarak geçirilir Foo.b.__get__(foo, Foo) ve Python niteliğini, kullanım için Sorumluluk iddia ediyor. property, bu yöntemlerin her ihtimale karşı çağrı*, fset, *20 fdel property kurucu geçtin.

Betimlemeleri gerçekten tüm OO uygulanması tesisat açığa Python yoludur. Aslında, tanımlayıcı başka tür property Daha fazla ortak var.

>>> class Foo(object):
...     def bar(self):
...         pass
... 
>>> Foo().bar
<bound method Foo.bar of <__main__.Foo object at 0x7f2a439d5dd0>>
>>> Foo().bar.__get__
<method-wrapper '__get__' of instancemethod object at 0x7f2a43a8a5a0>

Mütevazi yöntemi sadece tanımlayıcı bir başka türüdür. __get__ ilk argüman olarak arama örneği meseleye; aslında, bunu yapar:

def __get__(self, instance, owner):
    return functools.partial(self.function, instance)

Her neyse, bu tanımlayıcıları yalnızca dersleri çalışmak neden şüpheleniyorum: güçler ilk etapta sınıfları şeyler bir kayıt altına alıyorlar. Belli bir sınıf için tanımlayıcı atayabilirsiniz, ve sınıflar kendilerini type örnekleridir! hatta istisna onlar: Aslında, Foo.b okumaya çalışıyorum hala property.__get__; tanımlayıcıları sınıf öznitelikleri olarak erişilen kendilerini dönmek için sadece bir deyim var diyor.

Python'un OO sistem hemen hemen bütün Python ile ifade edilebilecek çok güzel bir şey bence. :)

Eğer ilgilenirsen Oh, ve yazdım wordy blog post about descriptors bir süre önce.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • EEVblog

    EEVblog

    4 NİSAN 2009
  • ThePointblank

    ThePointblan

    18 Aralık 2006
  • William Sledd

    William Sled

    24 EYLÜL 2006