2016-12-31 6 views
1

Ich versuche, ein Projekt mit class inheritance zu implementieren, wo Elternklasse ist:Python-Klasse - Attribut Vererbung

class radio: 

    def __init__(self, artist=None, track=None, genre=None): 

     self.artist = artist 
     self.track = track 
     self.genre = genre 

dann ich methods für jede attribute (nicht Arbeitsbeispiele) zu erstellen:

def seed_artist(self): 
     results = api.search(q=self.artist, type='artist') 
     return results 

    def seed_track(self): 
     results = api.search(q=self.track, type='track') 
     return results 

    def seed_genre(self): 
     results = api.search(q=self.genre, type='genre') 
     return results 

der Benutzer wird einen Samen über (nur einen) auswählen, sei es artist, track, genre oder mood, und deshalb initialisiere ich alle Argumente mit None, wobei der Argumentwert auf der Vererbungsebene eingefügt wird.

die geerbte class ist:

class playlist(radio): 

    def __init__(self,user): 
     radio.__init__(self, artist, track, genre) 

lässt ein Benutzereingaben sagen auf der Kommandozeile track seed, und mein Skript endet mit einer globalen Variablen Inbetriebnahme:

track = 'karma police' 

diese Weise alle anderen Attribute (artist, genre) bleiben None.

, wenn ich eine Instanz erstellen, sagen:

jeff = playlist('Jeff Smith') 

Es wirft einen Fehler sagen, dass genre und artist nicht definiert sind, und ich würde nur track Attribut erben haben, etwa so:

radio.__init__(self, track) 

ich weiß, ich könnte das Skript mit globalen Variablen starten definiert:

track = None 
genre = None 
artist = None 

und dies würde erlauben Sie mir zu haben:

radio.__init__(self, artist, track, genre) 

aber mir scheint eher überflüssig ...

Gibt es eine Abhilfe dies, ohne die Notwendigkeit für Anfangswerte der globalen Variablen auf None den gesamten Code innerhalb der Klassenbereichsdefinitionen behalten?

+0

Ich habe unten eine Antwort, aber es ist schwer zu sagen, was die Alternative für die globalen Variablen ist, weil Sie nicht haben gezeigt, oder Sie haben sogar beschrieben, wie Ihr Code von Benutzereingaben zu einer globalen Variablen namens 'tracks' gelangt. Eine Möglichkeit besteht darin, zu bewirken, dass "Playlist" auch "Track", "Interpret" usw. akzeptiert und dass Ihr Eingabe-Parsing-Code ein Diktat ähnlich wie in meiner Antwort beschrieben übergibt. – BrenBarn

+0

@BrenBarn Ich habe die Frage für Sie bearbeitet, falls Sie Ihre Antwort bearbeiten möchten. –

Antwort

1

Verwenden Sie anstelle einer separaten globalen Variablen für jedes Feld ein einzelnes Wörterbuch für alle Felder. Dann können Sie das Wörterbuch als Schlüsselwortargumente übergeben.

Das heißt, anstatt eine globale Variable namens artist zu erstellen, erstellen Sie ein Wörterbuch mit der Bezeichnung radio_fields oder so. Wenn der Benutzer die Abfrage eingibt, setzen Sie eine Taste auf diesem dict:

radio_fields = {} 
... 
# when you get the user's command 
radio_fields['track'] = 'Karma Police' 

Jetzt können Sie radio.__init__(self, **radio_fields) nennen. Dies wird als Argumente übergeben, egal welche Schlüssel in radio_fields sind. Wenn es nur einen gibt, wird nur dieser übergeben, und die anderen nehmen ihre Standardwerte, wie Sie sie definiert haben, als Sie radio.__init__ definiert haben.

Möglicherweise gibt es eine bessere Möglichkeit, Ihr Gesamtprogramm zu strukturieren, aber es ist schwer zu sagen, basierend auf dem, was Sie hier gezeigt haben.Zum Beispiel ist unklar, warum playlist nur ein user Argument akzeptiert. Wenn playlist alle Feldargumente akzeptierte, die radio akzeptiert haben, konnte sie problemlos an radio übergeben werden.

0

Sie müssen diese Variablen nicht übergeben, also versuchen Sie nicht, sie zu übergeben. Die Elternklasse hat bereits Voreinstellungen für sie, also nur den einen Pass benötigen Sie:

radio.__init__(self, artist=artist) 
+0

Das Problem ist dann, er müsste eine Reihe von separaten Aufrufen schreiben, abhängig davon, welche Variablen definiert sind, zusammen mit einem Gewirr von 'if' Anweisungen, um zu entscheiden, welcher Aufruf zu verwenden ist. – BrenBarn

+0

aber ich weiß nicht, welche ich brauche ... Das ist der Anruf des Benutzers. –