Seite 1 von 1

Docstring vererben

Verfasst: Sonntag 6. Juni 2010, 14:42
von snafu
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. :)

Re: Docstring vererben

Verfasst: Sonntag 6. Juni 2010, 14:46
von DasIch
Metaklassen werden ebenfalls geerbt, dadurch kann man was machen.

Re: Docstring vererben

Verfasst: Sonntag 6. Juni 2010, 15:00
von snafu
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.

Re: Docstring vererben

Verfasst: Sonntag 6. Juni 2010, 16:30
von Darii
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__

Re: Docstring vererben

Verfasst: Sonntag 6. Juni 2010, 17:49
von str1442
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.

Re: Docstring vererben

Verfasst: Sonntag 6. Juni 2010, 18:01
von snafu
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.