2016-10-04 3 views
-1

Was die sauberste und die meisten pythonic Weg, dies zu lösen:Pythonic Superklasse mit Klassenmethoden Konstruktor: überschreiben, erben, ...?

eine Klasse mit einem @classmethod Konstruktor wie in Codeb. 1. Aber jetzt Unterklasse mit zwei Klassen gegeben, die sowohl ein ganz anderes zusätzliches Argument erfordern, wie zum Beispiel in Codebeispiel 2. Sollte dies unter Verwendung von *args, **kwargs (Beispiel 3) gelöst werden? Oder sollte ich die @classmethod nicht erben, sondern in jeder Klasse kopieren? Oder erstellen Sie eine Superklasse def read_csv und beziehen sich auf die Unterklassen '@classmethod?

Unterklassen sind notwendig, da es in den Klassen andere komplexe Funktionen gibt.

Andere Personen, die mit diesem Code arbeiten, sollten wissen, welche Argumente bei der Initialisierung der verschiedenen Klassen zu übergeben sind.

Codebeispiel 1

class Car(object): 
    @classmethod 
    def from_csv(cls, csv): 
     df = pd.read_csv(csv) 
     # could be more complex 
     return cls(df) 

    def __init__(self, df): 
     self.df = df 

Codebeispiel 2

class Ferrari(Car): 
    def __init__(self, df, ferrari_logo): 
     self.df = df 
     self.ferrari_logo = ferrari_logo 

    def somethingcomplex(self): 
     #complex ferrari method 

def Fiat(Car): 
    def __init__(self, df, fiat_wheels): 
     self.df = df 
     self.fiat_wheels = fiat_wheels 

    def somethingcomplex(self): 
     #complex fiat method 

Fiat.from_csv('fiat.csv', fiat_wheels=8) 
Ferrari.from_csv('ferrari.csv', ferrari_logo='logo.jpg') 

Codebeispiel 3

class Car(object): 
    @classmethod 
    def from_csv(cls, csv, *args, **kwargs): 
     df = pd.read_csv(csv) 
     # could be more complex 
     return cls(df, *args, **kwargs) 

    def __init__(self, df): 
     self.df = df 
+0

"die sauberste und am meisten pythonische Art" sieht aus wie meine Meinung zu mir. Auch Sie haben bereits eine funktionierende Lösung und es ist sauber und pythonisch genug. Wenn Sie denken, dass etwas in Ihrer Lösung nicht stimmt und Sie nach Wegen suchen, um es zu verbessern, möchten Sie vielleicht die Frage neu formulieren, zumindest würde es ein tatsächliches Problem zu lösen geben. – Goyo

Antwort

1

ich glaube, Sie könnten vermeiden eine neue Unterklasse definieren (und Subklassifizieren insgesamt) jedes Mal, wenn Sie für die Car Klasse ein neues Attribut haben, indem sie die Attribute jeder Instanz von dem auf die __init__ Methode der Klasse bestanden kwargs Einrichtung:

class Car(object): 
    @classmethod 
    def from_csv(cls, csv, **kwargs): 
     df = pd.read_csv(csv) 
     # could be more complex 
     return cls(df, **kwargs) 

    def __init__(self, df=None, **kwargs): 
     self.df = df 
     for kw in kwargs: 
      setattr(self, kw, kwargs[kw]) 

Dann könnten Sie tun:

ferrari = Car.from_csv('some.csv', name='ferrari', ferrari_logo='logo.jpg') 
fiat = Car.from_csv('fiat.csv', name='fiat', fiat_wheels=8) 

Update:

Dann könnten Sie die obige Unterklasse erstellen, wenn Sie separate Methoden auf der Unterklassenebene definieren müssen. Sie müssen keine separate __init__ für jede Unterklasse schreiben.

+0

Danke für Ihre Antwort. Subclassing ist erforderlich, da es auch andere Funktionen in diesen Klassen gibt. Ich habe mein Beispiel ein wenig zu einfach (aktualisiert) –

+1

@LaurensKoppenol Oh, dann könnten Sie diese Lösung Unterklasse. Dann brauchen Sie kein '__init__' für jede Unterklasse. Nur die erforderlichen Methoden werden auf der Subklassenebene –

+0

definiert. Dies ist eine funktionierende Lösung, aber meine Mitarbeiter können nicht einfach mit meinen Klassen arbeiten, da nicht sichtbar ist, welche ** kwargs der Unterklassen benötigt/optional sind und nicht angezeigt werden die Dokumente des __init__ der Unterklassen –

Verwandte Themen