2016-04-13 16 views
0

Der Titel der Frage mag sehr seltsam sein, aber ich hatte keine Ahnung, wie ich es anders formulieren sollte. Ich suche nach Hilfe beim Verständnis von Klasseninstanziierung und Variablenreferenzierung in Python, insbesondere wenn eine Klassenvariable eine Instanz einer anderen Klasse ist. Ich werde das dlipower Python-Modul verwenden, da das ist, woran ich gerade arbeite.Referenzieren der Instantiierung der Klasse in einer anderen Klasse

dlipower besteht aus zwei Klassen, dlipower.PowerSwitch() und dlipower.Outlet(switch). Outlet(switch) erfordert eine Instanz von PowerSwitch() als erstes Argument. Ich habe eine Klasse geschrieben, die diese beiden Klassen verwendet, aber ich habe keine Ahnung, wie ich auf die Instanz PowerSwitch verweisen kann, ohne sie in jeder Funktion, die ich habe, zu instanziieren. Ich tue etwas ähnlich der folgenden jetzt:

import dlipower 
class dli: 
    switch = dlipower.PowerSwitch() # should this be here? 
    def __init__(self): 
     pass 
    def PowerOn(self, port): 
     switch = dlipower.PowerSwitch() # this is what I want to remove 
     outlet = dlipower.Outlet(switch) 
     outlet.on(port) 

Ich habe während Python-Code wurde Codierung, aber immer noch sehr neu in OOP, so dass alle Tipps und Hinweise wäre eine große Hilfe sein.

+0

Haben Sie 'dli.switch' probiert? – TigerhawkT3

+0

Ich bin mir nicht sicher, ob es eine einzige Antwort auf diese Frage gibt. Welche Semantik ist mit dem Schalter verbunden, den Sie an den Konstruktor "Outlet" übergeben? Wenn Sie es wiederverwenden, funktioniert es anders? Wenn es zwischen vielen 'dli' Instanzen geteilt wird, ist das wichtig? Es ist mir nicht klar, warum Sie überhaupt eine 'dli'-Klasse haben, da Sie sie niemals zum Speichern von Daten verwenden (als Attribute). – Blckknght

+0

@Blckknght der einzige Grund, warum ich eine dli Klasse habe, ist die Instantiierung von 'switch' zwischen allen Methoden in' dli' zu teilen. Ich habe hier nur eine Funktion eingefügt, um meinen Punkt zu verdeutlichen, aber was ich tatsächlich in Instanzen von 'PowerSwitch()' erstellt habe, was ich vermute, verlangsamt das Skript. 'switch' ist in der gesamten Klasse gleich und es gibt keinen Unterschied in den verschiedenen Anwendungen. Für diese spezielle Klasse brauche ich außer "switch" keine Attribute. – atf

Antwort

0

Wenn Ihre Methode auf eine Klassenvariable zugreifen soll, müssen Sie über den Klassennamen oder über self darauf zugreifen. Entweder man sollte funktionieren:

class dli: 
    switch = dlipower.PowerSwitch() 
    # no need for an empty __init__ method 
    def PowerOn(self, port): 
     outlet = dlipower.Outlet(dli.switch) 
     outlet.on(port) 

Oder:

class dli: 
    switch = dlipower.PowerSwitch() 
    def PowerOn(self, port): 
     outlet = dlipower.Outlet(self.switch) 
     outlet.on(port) 

Dies erschafft noch die outlet jedes Mal, wenn PowerOn nennen, aber vielleicht ist das billig ...

Sie brauchen nicht wirklich ein Klasse dafür. Die Klassenvariable switch ist nur eine globale Variable im Klassennamespace. Da Sie keine anderen Attribute haben Sie (entweder Klassenattribute oder Instanzattribute), könnte es einfacher sein, nur um stattdessen eine tatsächliche globale zu verwenden:

# no dli class needed any more, just use top level variables and functions! 

_switch = dlipower.PowerSwitch() # create a global PowerSwitch 

def PowerOn(port): 
    outlet = dlipower.Outlet(_switch) 
    outlet.on(port) 

ich einen Namen mit einem Unterstrich für die globale Variable verwendet haben . Das weist andere Programmierer darauf hin, dass es sich um ein internes Implementierungsdetail handelt, das nicht Teil der API Ihres Moduls ist. Es ist nicht "privat" in der Art, wie einige andere Programmiersprachen meinen (wo der Compiler anderen Code daran hindert, darauf zuzugreifen), aber es ist Pythons Version von privat (wo anderer Code ist entmutigt verhindert verhindert Zugriff auf interne Sachen).

Apropos Namenskonventionen, vielleicht möchten Sie Ihre ändern. Die gebräuchlichste Konvention für Python-Code ist die Verwendung von CaptializedNames nur für Klassen und lower_case_names_with_underscores für die meisten anderen Dinge (Funktionen, Variablen usw.).Die Verwendung einer anderen Konvention ist nicht falsch per se, aber es kann es für andere schwieriger machen, Ihren Code zu lesen.

+0

Ich habe beide Möglichkeiten in meinem Hauptskript versucht und ich bekomme immer noch das gleiche Problem, dass 'switch' deinstalliert wird. Ich versuche die gleichen Methoden in einem separaten Skript und sie funktionieren gut. Ich habe mich meiner Klasseninstanziationen und meiner Globals versichert, aber ich habe immer noch keine Ahnung, was schiefgehen könnte ... Danke für die Tipps, übrigens :) – atf

+0

Ich habe herausgefunden, was das Problem war: Ich habe das Programm instanziiert 'switch' mit einer leeren Passwort-Variable, auch wenn ich die Variable später im Skript ändere, gibt es immer noch kein Passwort, was den Fehler verursacht hat. Danke für die Hilfe! – atf

0

Wenn Sie versuchen, eine bestimmte Instanz eines Power Objekt in das Outlet-Objekt übergeben Sie in der PowerOn Funktion sind instanziiert wird, geben sie in die Funktion als Argument, als solche:

def PowerOn(self, port, switch): 
    outlet = dlipower.Outlet(switch) 
    outlet.on(port) 

Wann immer Sie ein neues Outlet instanziieren möchten, instanziieren Sie den PowerSwitch vor dem Funktionsaufruf und fügen Sie ihn als Argument ein.

Um auf eine Variable außerhalb einer bestimmten Funktion innerhalb einer Funktion zu verweisen, muss diese Variable global (außerhalb jeder Funktion oder Klasse erstellt), eine Klassenvariable (außerhalb einer Funktion innerhalb einer Klasse erstellt) und eine Variable erstellt werden innerhalb der Funktion oder ein mit der Funktion bereitgestelltes Argument.

Verwandte Themen