2016-07-29 4 views
0

Ich habe eine Klasse von Form bekam:Subfunktion Referenzierung ohne Objekt declation

class MyClass(object): 
    def curves(self): 
    def plot(self): 
     plot a graph 
     return something 
    return a pd.DataFrame 

Was will ich etwas tun definieren ist, kann ich anrufen mit instance_of_my_class.curves.plot()

Muss ich Kurven als definieren, Objekt, um dies zu ermöglichen? Ich suche den kürzesten Weg, um dies zu tun, da dies nur syntaktischer Zucker ist.

Danke.

+1

Wenn Sie anrufen möchten 'instance_of_my_class.curves.plot()' es ist ein Objekt sein, oder zumindest etwas mit einstellbaren Attributen. Momentan ist Ihr 'plot()' nur innerhalb der Umgebung der Funktion 'curves()' definiert, wenn es aufgerufen wird. dh "plot()' wird nur erzeugt, wenn man 'curves()' aufruft und nur innerhalb von 'curves()' zugänglich ist. – Eric

+0

Ist 'plot' mit einer der Variablen innerhalb von' curves', z. "Selbst" oder was auch immer sonst, das du in diesem kurzen Beispiel nicht zeigst? Wenn ja, wie groß sollten diese Variablen sein, wenn sie "außerhalb" von "Kurven" genannt werden? Wenn nicht, warum definieren Sie es zuerst in "Kurven"? –

+0

@jojo Klassenmethoden erhalten die Instanz nicht übergeben? – poke

Antwort

0

Um eine Hierarchieebene hinzuzufügen, muss curves ein tatsächliches Objekt sein, ja. Es gibt keinen Unterschied zwischen foo.curves.plot() und dem folgenden:

c = foo.curves 
c.plot() 

So braucht foo.curves ein Objekt zu sein, das eine plot Methode hat.

Da die Methode für das Objekt aufgerufen wird, wird die Methode außerdem an das Objekt gebunden. Wenn Sie es nicht auf diese Weise einrichten, hat das Objekt curves keinen Zugriff auf Ihre tatsächliche Klasse.

Sie könnten die Instanz im curves Konstruktor aber:

class Curves (object): 
    def __init__ (self, parent): 
     self.parent = parent 
    def plot (self): 
     self.parent._plot() 

class MyClass (object): 
    def __init__ (self): 
     self.curves = Curves(self) 
    def _plot (self): 
     print('Actual plot implementation') 

Dann können Sie es als foo.curves.plot() verwenden:

>>> foo = MyClass() 
>>> foo.curves.plot() 
Actual plot implementation 

Sie konnten dieses ein wenig automatisieren, indem eine mit descriptor für curves. Zum Beispiel ist dies eine mögliche Lösung:

class Accessor (object): 
    def __init__ (self, prefix = ''): 
     self.prefix = prefix 
    def __get__ (self, instance, owner): 
     return AccessorDelegate(instance, self.prefix) 

class AccessorDelegate (object): 
    def __init__ (self, instance, prefix): 
     self.instance = instance 
     self.prefix = prefix 
    def __getattr__ (self, name): 
     return getattr(self.instance, self.prefix + name) 

Der Vorteil ist offensichtlich, dass Sie nur diejenigen, die ein einziges Mal definieren müssen und dann werden sie für alle Klassen arbeiten. Sie würde es so in Ihrer Klasse verwenden:

class MyClass (object): 
    curves = Accessor('_curves_') 

    def _curves_plot(self): 
     print('Implementation of curves.plot') 

Gebrauchte genau wie oben:

>>> foo = MyClass() 
>>> foo.curves.plot() 
Implementation of curves.plot