Docstring vererben

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich möchte in Zusammenhang mit Callisto einen einheitlichen Docstring für die `render()`-Methode eines Renderers schaffen. Das ist so gedacht: Es gibt die Klasse `Renderer`, von der geerbt werden soll. Sie selbst implementiert nur die Doku. Der Code für die Funktion wird von der jeweils abgeleiteten Klasse übernommen. Ziel ist also, den Docstring an die jeweilige `render()`-Methode der abgeleiteten Klasse automatisch anzuheften, sofern noch kein Docstring definiert ist.

Meine Versuche mit `super()` sind bisher kläglich gescheitert. Mir kam noch die Idee einer Metaklasse, aber es ist mir zu umständlich, wenn alle Renderer gezwungen sind, das `__metaclass__`-Attribut zu setzen, was ja - zumindest habe ich das bisher so verstanden - Grundvoraussetzung ist. Bei den Snippets, die man zu dem Thema im Internet findet, weiß ich nicht so recht, ob man sich das echt so kompliziert machen muss. Teilweise wird da mit `__new__` sozusagen als Wrapper u.ä. rumgespielt.

Macht mal bitte Vorschläge, wie ihr es machen würdet. :)
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Metaklassen werden ebenfalls geerbt, dadurch kann man was machen.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Naja, ich habe schon den `@abstractmethod`-Dekorator angesehen und so. Aber entweder ich schnall es nicht oder es geht nicht. Jedenfalls komme ich nicht dahinter, wie dann ein Attribut (`__doc__` eben) der erbenden Klasse verändert werden kann.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

snafu hat geschrieben:Naja, ich habe schon den `@abstractmethod`-Dekorator angesehen und so. Aber entweder ich schnall es nicht oder es geht nicht. Jedenfalls komme ich nicht dahinter, wie dann ein Attribut (`__doc__` eben) der erbenden Klasse verändert werden kann.
Indem du im __new__ der Metaklasse den Docstring aus den zu entsprechenden Funktionen der Basisklassen in die der Unterklasse kopierst.

Irgendwie sowas:

Code: Alles auswählen

from abc import abstractmethod, ABCMeta

class CopyDoctring(ABCMeta):
    def __new__(self, name, bases, dict):
        for base in bases:
            for item_name, item in base.__dict__.iteritems():
                if getattr(item, "__isabstractmethod__", False):
                    try:
                        new_func = dict[item_name]
                        if not new_func.__doc__:
                            new_func.__doc__ = item.__doc__
                    except KeyError: pass
        return ABCMeta.__new__(self, name, bases, dict)

class AbstractClass(object):
    __metaclass__ = CopyDoctring
    @abstractmethod
    def get_2(self):
        "returns 2"
        pass

class Class(AbstractClass):
    def get_2():
        return 2

print Class.get_2.__doc__
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Täusche ich mich, oder ist hier ein Klassendekorator geeigneter und "natürlicher" (Jede Klasse, die diese einleuchtende aber ungewöhnliche Eigenschaft hat ist dann entsprechend "annotiert" in Dekorator Manier)? Man könnte jetzt auch noch den Standard Docstring mittels format() spezialisieren lassen, aber vielleicht ist das Overkill für die angestrebte Verwendung.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich frage mich gerade generell, ob man sowas unbedingt braucht. Da es bei "reiner" Vererbung offenbar nicht ohne größere Verrenkungen klappt und ich einen Dekorator dafür übertrieben finde, werde ich mich wohl von der Idee verabschieden.
Antworten