Vererbung & Ausdrücke

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
nezzcarth
User
Beiträge: 1792
Registriert: Samstag 16. April 2011, 12:47

Hallo :)

mir ist letztens klar geworden, dass man in Python soetwas schreiben kann:

(Python 3.5.1)

Code: Alles auswählen

import inspect
from random import choice
 
SWITCH = True
class Test(int if SWITCH else float):
    def __init__(self):
        pass

print(inspect.getmro(Test))
SWITCH = False
print(inspect.getmro(Test))

class Test2(choice((int, float, str))):
    def __init__(self):
        pass

print(inspect.getmro(Test2))

Code: Alles auswählen

$ python test.py
(<class '__main__.Test'>, <class 'int'>, <class 'object'>)
(<class '__main__.Test'>, <class 'int'>, <class 'object'>)
(<class '__main__.Test2'>, <class 'str'>, <class 'object'>)

$ python test.py
(<class '__main__.Test'>, <class 'int'>, <class 'object'>)
(<class '__main__.Test'>, <class 'int'>, <class 'object'>)
(<class '__main__.Test2'>, <class 'float'>, <class 'object'>)


Besonders sinnvoll ist das nicht, da der Ausdruck ja nur bei der Klassendefinition ausgewertet wird und ein "echtes" Kontext-bedingtes Ändern der Elternklassen zur Laufzeit nicht möglich ist.
Gibt es irgendeinen Grund bzw. eine Anwendung dafür, an der Stelle (bestimmte) Ausdrücke schreiben zu können, oder ist das einfach ein Nebeneffekt der Grammatik?
Benutzeravatar
snafu
User
Beiträge: 6908
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ein bedingter Ausdruck ist an jeder Stelle möglich, wo ein Bezeichner stehen kann. Ich fände es komisch, wenn die Grammatik hier bei Klassendefinitionen eine Ausnahme machen würde.

Ein Anwendungsbeispiel, wo dieses Vorgehen sinnvoll wäre, sehe ich jedoch nicht. Wenn man verschiedene Klassen auf die gleiche Art erweitern möchte, dann verwendet man normalerweise Mixins.
BlackJack

@nezzcarth: Das dort Ausdrücke stehen können kann man beispielsweise mit `collections.namedtuple()` sinnvoll nutzen wenn man zusätzliche Methoden haben möchte:

Code: Alles auswählen

class Point(namedtuple('Point', 'x y')):

    def distance_to(self, other):
        return sqrt((self.x - other.x)**2 + (self.y - other.y)**2)
Ansonsten schliesse ich mich snafu an, dass es die Grammatik an der Stelle komplizierter machen würde wenn man die Ausdrücke die dort möglich sind einschränken würde.
nezzcarth
User
Beiträge: 1792
Registriert: Samstag 16. April 2011, 12:47

Danke für das Beispiel, BlackJack.

Ja, es stimmt natürlich, dass eine zusätzliche Einschränkung hier eher seltsam wäre (im Grunde ist das Zeile 8 des Python-Zen). Ich finde es trotzdem ungünstig, dass an der Stelle gewissermaßen ein toter Winkel existiert, der aus der Interaktion zweier Prinzipien entsteht und man "(halb)wirkungslosen Code" schreiben kann; wie man's besser machen kann, wüsste ich allerdings auch nicht :)
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@nezzcarth: man kann so ziemlich überall „wirkungslosen“ Code schreiben. Wollte man das überall verbieten hätte man einen Compiler von der Komplexität von C++.
Antworten