Πώς μπορώ απλά να κληρονομήσει μεθόδους από ένα υπάρχον παράδειγμα;

ψήφοι
0

Παρακάτω έχω ένα πολύ απλό παράδειγμα αυτό που προσπαθώ να κάνω. Θέλω να είμαι σε θέση να χρησιμοποιήσει HTMLDecorator με οποιαδήποτε άλλη κατηγορία. Αγνοήστε το γεγονός αυτό λέγεται διακοσμητής, είναι απλά ένα όνομα.

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()

Παραγωγή:

Traceback (πιο πρόσφατη κλήση τελευταία):
  Αρχείο html.py, γραμμή 21, σε 
    HTMLDecorator εκτύπωσης (inst_x) .html ()
TypeError: προεπιλογή __new__ δεν παίρνει παραμέτρους

Είναι αυτό που προσπαθώ να κάνω είναι δυνατόν; Αν ναι, τι κάνω λάθος;

Δημοσιεύθηκε 01/09/2008 στις 04:17
πηγή χρήστη
Σε άλλες γλώσσες...                            


6 απαντήσεις

ψήφοι
0

Είναι αυτό που προσπαθώ να κάνω είναι δυνατόν; Αν ναι, τι κάνω λάθος;

Είναι σίγουρα εφικτή. Ποιο είναι το πρόβλημα είναι ότι HTMLDecorator.__init__()δεν δέχεται παραμέτρους.

Εδώ είναι ένα απλό παράδειγμα:

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
Απαντήθηκε 01/09/2008 στις 04:26
πηγή χρήστη

ψήφοι
0

@John (37448):

Συγγνώμη, θα μπορούσα να έχω να σας παραπλάνησε με το όνομα (κακή επιλογή). Δεν είμαι πραγματικά ψάχνει για μια λειτουργία διακοσμητής, ή οτιδήποτε έχει να κάνει με διακοσμητές καθόλου. Τι είμαι μετά είναι για την def html (αυτο) να χρησιμοποιούν ClassX ή αριστοκρατικό του __repr__. Θέλω να λειτουργήσει χωρίς τροποποίηση ClassX ή αριστοκρατικό.

Απαντήθηκε 01/09/2008 στις 05:10
πηγή χρήστη

ψήφοι
0

Αχ, σε αυτή την περίπτωση, ίσως κώδικα όπως αυτό θα είναι χρήσιμο; Δεν έχει τίποτα να κάνει με διακοσμητές, αλλά δείχνει πώς να περάσει επιχειρήματα σε λειτουργία αρχικοποίησης μια τάξη και να ανακτήσετε τα επιχειρήματα αυτά για αργότερα.

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()
Απαντήθηκε 01/09/2008 στις 05:25
πηγή χρήστη

ψήφοι
0

@John (37479):

Πολύ κοντά, αλλά τότε θα χάσουμε τα πάντα, από ClassX. Παρακάτω είναι κάτι συνάδελφός μου έδωσε που δεν κάνει το κόλπο, αλλά είναι αποτρόπαιο. πρέπει να υπάρχει ένας καλύτερος τρόπος.

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()

Παραγωγή:

<H1> Best Guess </ H1>
<H1> <__ κύρια __. Αριστοκρατικό αντικείμενο σε 0x891df0c> </ 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> True </ H1>
Απαντήθηκε 01/09/2008 στις 05:55
πηγή χρήστη

ψήφοι
2

Πολύ κοντά, αλλά τότε θα χάσουμε τα πάντα, από ClassX. Παρακάτω είναι κάτι συνάδελφός μου έδωσε που δεν κάνει το κόλπο, αλλά είναι αποτρόπαιο. πρέπει να υπάρχει ένας καλύτερος τρόπος.

Φαίνεται σαν να προσπαθείτε να δημιουργήσει κάποιο είδος συστήματος μεσολάβησης αντικειμένου. Αυτό είναι εφικτό, και υπάρχουν καλύτερες λύσεις από τον συνάδελφό σας, αλλά πρώτα να εξετάσει κατά πόσον θα ήταν πιο εύκολο να επιδιορθώσει σε κάποια επιπλέον μεθόδους. Αυτό δεν θα λειτουργήσει για built-in τάξεις όπως bool, αλλά θα για τις κατηγορίες καθορίζονται από το χρήστη σας:

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

Και εδώ είναι η έκδοση μεσολάβησης:

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)
Απαντήθηκε 01/09/2008 στις 06:33
πηγή χρήστη

ψήφοι
2

Και οι δύο λύσεις Ιωάννη θα μπορούσε να λειτουργήσει. Μια άλλη επιλογή που επιτρέπει HTMLDecorator να παραμένει πολύ απλό και καθαρό είναι να μαϊμού-μπάλωμα ως μια βασική κλάση. Αυτό λειτουργεί, επίσης, μόνο για τις κατηγορίες ορίζονται από το χρήστη, δεν ενσωματωμένες τύπους:

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()

Να προειδοποιούνται, αν και - μαϊμού-μπαλώματα όπως αυτό έρχεται με μια υψηλή τιμή σε αναγνωσιμότητα και η συντηρησιμότητα του κώδικα σας. Όταν πας πίσω σε αυτό το κώδικα ένα χρόνο αργότερα, μπορεί να γίνει πολύ δύσκολο να καταλάβω πώς ClassX σας πήρε αυτή τη μέθοδο html (), ειδικά αν ClassX ορίζεται σε κάποια άλλη βιβλιοθήκη.

Απαντήθηκε 01/09/2008 στις 07:30
πηγή χρήστη

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