Basitçe nasıl varolan örneğinden yöntemleri devralabilir?

oy
0

Aşağıda ben yapmaya çalışıyorum şeyin çok basit bir örnek var. Başka sınıfla HTMLDecorator kullanmak isterler. bu sadece bir isim, bu dekoratör deniyor gerçeğini görmezden.

import cgi

class ClassX(object):
  pass # ... with own __repr__

class ClassY(object):
  pass # ... with own __repr__

inst_x=ClassX()

inst_y=ClassY()

inst_z=[ i*i for i in range(25) ]

inst_b=True

class HTMLDecorator(object):
   def html(self): # an enhanced version of __repr__
       return cgi.escape(self.__repr__()).join((<H1>,</H1>))

print HTMLDecorator(inst_x).html()
print HTMLDecorator(inst_y).html()
wrapped_z = HTMLDecorator(inst_z)
inst_z[0] += 70
wrapped_z[0] += 71
print wrapped_z.html()
print HTMLDecorator(inst_b).html()

Çıktı:

Traceback (en son çağrı son):
  Dosya html.py, hat 21'de 
    Baskı HTMLDecorator (inst_x) .html ()
TypeError: Varsayılan __new__ hiçbir parametre alır

Ben mümkün yapmaya çalıştığım şey var mı? Eğer öyleyse, ben yanlış yapıyorum?

Oluştur 01/09/2008 saat 04:17
kaynak kullanıcı
Diğer dillerde...                            


6 cevaplar

oy
0

Ben mümkün yapmaya çalıştığım şey var mı? Eğer öyleyse, ben yanlış yapıyorum?

Bu kesinlikle mümkün. Yanlış olmasıdır HTMLDecorator.__init__()parametreleri kabul etmez.

İşte basit bir örnek:

def decorator (func):
    def new_func ():
        return "new_func %s" % func ()
    return new_func

@decorator
def a ():
    return "a"

def b ():
    return "b"

print a() # new_func a
print decorator (b)() # new_func b
Cevap 01/09/2008 saat 04:26
kaynak kullanıcı

oy
0

@John (37.448):

Üzgünüm, adı (kötü bir seçim) ile yanıltılmış olabilir. Gerçekten hiç dekoratörler ile yapmak için bir dekoratör fonksiyonu, ya da bir şey aramıyorum. Ne Peşinde olduğum ClassX veya klas kullanmak html (kendinden) def içindir __repr__. Bu ClassX veya klas değiştirmeden çalışmak istiyorum.

Cevap 01/09/2008 saat 05:10
kaynak kullanıcı

oy
0

Ah, bu durumda, belki böyle kod faydalı olacaktır? Gerçekten dekoratörler ile ilgisi yok, ama bir sınıfın başlatma fonksiyonu argüman geçmek ve sonrası için bu argümanları alma gösterilmiştir etmez.

import cgi

class ClassX(object):
    def __repr__ (self):
        return "<class X>"

class HTMLDecorator(object):
    def __init__ (self, wrapped):
        self.__wrapped = wrapped

    def html (self):
        sep = cgi.escape (repr (self.__wrapped))
        return sep.join (("<H1>", "</H1>"))

inst_x=ClassX()
inst_b=True

print HTMLDecorator(inst_x).html()
print HTMLDecorator(inst_b).html()
Cevap 01/09/2008 saat 05:25
kaynak kullanıcı

oy
0

@John (37.479):

Çok yakın, ama daha sonra ClassX her şeyi kaybeder. Aşağıda hile yapmak yapan bir collegue bana verdiği şey, ama iğrenç. Daha iyi bir yol olmalı.

import cgi
from math import sqrt

class ClassX(object): 
  def __repr__(self): 
    return "Best Guess"

class ClassY(object):
  pass # ... with own __repr__

inst_x=ClassX()

inst_y=ClassY()

inst_z=[ i*i for i in range(25) ]

inst_b=True

avoid="__class__ __init__ __dict__ __weakref__"

class HTMLDecorator(object):
    def __init__(self,master):
        self.master = master
        for attr in dir(self.master):
            if ( not attr.startswith("__") or 
                attr not in avoid.split() and "attr" not in attr):
                self.__setattr__(attr, self.master.__getattribute__(attr))

    def html(self): # an "enhanced" version of __repr__
        return cgi.escape(self.__repr__()).join(("<H1>","</H1>"))

    def length(self):
        return sqrt(sum(self.__iter__()))

print HTMLDecorator(inst_x).html()
print HTMLDecorator(inst_y).html()
wrapped_z = HTMLDecorator(inst_z)
print wrapped_z.length()
inst_z[0] += 70
#wrapped_z[0] += 71
wrapped_z.__setitem__(0,wrapped_z.__getitem__(0)+ 71)
print wrapped_z.html()
print HTMLDecorator(inst_b).html()

Çıktı:

<H1> En İyi Tahmin </ H1>
<H1> <0x891df0c de __ ana __. Klas nesne> </ H1>
70,0
<H1> [141, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576] </ H1>
<H1> Doğru </ H1>
Cevap 01/09/2008 saat 05:55
kaynak kullanıcı

oy
2

Çok yakın, ama daha sonra ClassX her şeyi kaybeder. Aşağıda hile yapmak yapan bir collegue bana verdiği şey, ama iğrenç. Daha iyi bir yol olmalı.

Eğer vekil nesne şeması çeşit kurmaya çalıştığı gibiler. O Yapılabilir, ve iş arkadaşınız daha mı iyi çözüm bulunmaktadır, ama önce sadece bazı ekstra yöntemler içinde yama daha kolay olacağını düşünün. Bu gibi yerleşik sınıflar için çalışmaz bool, ancak kullanıcı tanımlı sınıflar için yapacaktır:

def HTMLDecorator (obj):
    def html ():
        sep = cgi.escape (repr (obj))
        return sep.join (("<H1>", "</H1>"))
    obj.html = html
    return obj

Ve burada vekil sürümü:

class HTMLDecorator(object):
    def __init__ (self, wrapped):
        self.__wrapped = wrapped

    def html (self):
        sep = cgi.escape (repr (self.__wrapped))
        return sep.join (("<H1>", "</H1>"))

    def __getattr__ (self, name):
        return getattr (self.__wrapped, name)

    def __setattr__ (self, name, value):
        if not name.startswith ('_HTMLDecorator__'):
            setattr (self.__wrapped, name, value)
            return
        super (HTMLDecorator, self).__setattr__ (name, value)

    def __delattr__ (self, name):
        delattr (self.__wraped, name)
Cevap 01/09/2008 saat 06:33
kaynak kullanıcı

oy
2

John'un çözümlerinin Hem çalışacak. HTMLDecorator çok basit ve temiz kalmasını sağlayan bir diğer seçenek bir temel sınıf olarak maymun yama onu içinde olmaktır. Bu aynı zamanda kullanıcı tanımlı sınıflar değil, yerleşik türleri için çalışır:

import cgi

class ClassX(object):
    pass # ... with own __repr__

class ClassY(object):
    pass # ... with own __repr__

inst_x=ClassX()
inst_y=ClassY()

class HTMLDecorator:
    def html(self): # an "enhanced" version of __repr__
        return cgi.escape(self.__repr__()).join(("<H1>","</H1>"))

ClassX.__bases__ += (HTMLDecorator,)
ClassY.__bases__ += (HTMLDecorator,)

print inst_x.html()
print inst_y.html()

Dikkat edin, gerçi - maymun yama bu gibi bir kod yüksek okunabilirliği fiyatın ve bakımı ile gelir. Bir yıl sonra bu koda geri döndüğünüzde, bu ClassX başka kitaplığında tanımlanan, özellikle eğer ClassX o html () yöntemini nasıl aldığını anlamaya çok zorlaşabilir.

Cevap 01/09/2008 saat 07:30
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more