2013-06-12 5 views
7

ich versuche, meine eigene Version eines DailyLogFilePython: Warum eine Methode aus der Superklasse nicht gesehen?

from twisted.python.logfile import DailyLogFile 

class NDailyLogFile(DailyLogFile): 

    def __init__(self, name, directory, rotateAfterN = 1, defaultMode=None): 
     DailyLogFile.__init__(self, name, directory, defaultMode) # why do not use super. here? lisibility maybe? 
     # 
     self.rotateAfterN = rotateAfterN 

    def shouldRotate(self): 
     """Rotate when N days have passed since file creation""" 
     delta = datetime.date(*self.toDate()) - datetime.date(*self.toDate(self.createdOn)) 
     return delta > datetime.timedelta(self.rotateAfterN) 

    def __getstate__(self): 
     state = BaseLogFile.__getstate__(self) 
     del state["rotateAfterN"] 
     return state 

threadable.synchronize(NDailyLogFile) 

zu implementieren, aber es sieht aus wie ich eine grundlegende Python Subklassifizieren Prozess verpassen ... wie ich diese Fehlermeldung erhalten:

Traceback (most recent call last): 
    File "/home/twistedtestproxy04.py", line 88, in <module> 
    import ndailylogfile 
    File "/home/ndailylogfile.py", line 56, in <module> 
    threadable.synchronize(NDailyLogFile) 
    File "/home/lt/mpv0/lib/python2.6/site-packages/twisted/python/threadable.py", line 71, in synchronize 
    sync = _sync(klass, klass.__dict__[methodName]) 
KeyError: 'write' 

i so müssen explizit hinzufügen und andere Methoden wie Write und rotate Methode wie folgt definieren:

class NDailyLogFile(DailyLogFile): 
    [...] 
    def write(self, data): # why must i add these ? 
     DailyLogFile.write(self, data) 

    def rotate(self): # as we do nothing more than calling the method from the base class! 
      DailyLogFile.rotate(self) 

threadable.synchronize(NDailyLogFile) 

whi le ich dachte, dass es richtig von der Basismutterklasse erben würde. Beachten Sie, dass ich nichts tue, nur "super",

anrufen bitte kann jemand erklären, warum ich falsch bin auf meine erste Idee, dass es nicht notwendig war, die Write-Methode hinzuzufügen?

Gibt es eine Möglichkeit, zu Python in meinem NDailyLogFile zu sagen, dass es alle Methoden DailyLogFile haben sollte, die nicht direkt von seiner Mutterklasse definiert sind? So dass es diesen König von Fehler _sync(klass, klass.__dict__[methodName] verhindert und das excipicitly vermeiden zu spezifizieren?

(Original-Code von DailyLogFile, die mir aus der verdrehten Quelle hier https://github.com/tzuryby/freespeech/blob/master/twisted/python/logfile.py genommen inspiriert)

EDIT: über die Verwendung von super, erhalte ich:

File "/home/lt/inwork/ndailylogfile.py", line 57, in write 
    super.write(self, data) 
exceptions.AttributeError: type object 'super' has no attribute 'write' 

wird so nicht verwenden. Meine Gedanken waren, dass es richtig war ... ich muss definitiv etwas verpasst haben

+1

Von OOP-Perspektive machen Sie es richtig, außer Sie wollen nicht alle Methoden überschreiben. Und du solltest wirklich 'super' benutzen. Das Problem ist, dass 'threadable.py' nicht sehr freundlich zu diesem OOP-Zeug ist, da die Zeile, die einen Fehler auslöst, auf das Vorhandensein von' write' in * dieser bestimmten Klasse * achtet, aber nicht auf ihre Vorfahren. Ich habe keine Erfahrung mit "verdreht", also weiß ich nicht, wie ich das überwinden kann. Vielleicht gibt es irgendwo im Internet irgendwelche Anleitungen? – J0HN

+0

ok, danke für den Kommentar. Ich weiß nicht, ob es für jetzt eine bessere Antwort gibt. aber du hast einen guten Teil :) – user2468222

+0

Ich denke, die alberne und wahrscheinlich falsche Art zu erreichen, was du versuchst zu tun, ist das Ersetzen von 'class .__ dict __ [methodName]' durch 'getattr (klass, methodname)' in 'threadable .py'. Und höchstwahrscheinlich wird es nicht funktionieren. Und es ist ein Patch zu verdreht. Und es bricht wahrscheinlich etwas außerhalb dieses speziellen Anwendungsfalls. Also, bitte versuchen Sie es als einen Beweis des Konzepts und wenn es wirklich funktioniert - schlagen Sie als ein Patch vor, der über angeschlagene Listen oder Ticketverfolger verdreht wird, oder was auch immer sie verwenden, um Entwicklung zu fördern. Und vergessen Sie nicht, hier etwas zu posten, damit ich weiß, ob es geholfen hat :) – J0HN

Antwort

2

Ich wage zu sagen, dass der twisted/python/threadable.py Code einen Fehler darin hat. __dict__ gibt nur die lokalen Attribute zurück, nicht die geerbten Attribute. Otherposts sagen, dir() oder inspect.getmembers() zu verwenden, um sie zu erhalten.

Die gute Nachricht ist, dass Sie auf Ihre erste Idee, dass die write-Methode vererbt wird, richtig sind. Die schlechte Nachricht ist, dass Twisted geerbte Methoden nicht anerkennt, also müssen Sie sie selbst schreiben.

+0

'dir' wird eine Liste von Stuff-Attributen und Methoden zurückgeben, aber nicht die Methoden selbst. 'inspect.getmembers' gibt eine Liste von Tupel der Struktur (' name', 'value') zurück, so dass es möglich ist, eine Methode zu finden, aber schwerer als nur' getattr' zu verwenden. – J0HN

+0

also kann ich sie explizit aus der Unterklasse hinzufügen, ohne sie zu definieren? Ich bin mir nicht sicher, ob ich hier den Punkt verstehen könnte, wie ich 'dir' oder' inspect.getmembers() 'dafür verwenden könnte. – user2468222

+0

@ user2468222 Sie müssen 'threadable.py' trotzdem patchen, aber es ist auf eine eindringlichere Weise als mit' getattr' – J0HN

3

Es gibt ein Problem zu umgehen, einfach tun:

NDailyLogFile.__dict__ = dict(NDailyLogFile.__dict__.items() + DailyLogFile.__dict__.items()) 
threadable.synchronize(NDailyLogFile) 

Es gibt hier ein Problem, dass Sie die Klasse verwenden, ohne sie instanziiert zu haben. Diese Problemumgehung funktioniert, da Sie gezwungen sind, die Klassenattribute vor der Instanziierung zu ändern.

Ein weiterer wichtiger Kommentar ist, dass für eine Unterklasse von DailyLogFile der Befehl super nicht funktionieren würde, da DailyLogFile ist eine so „alte Stil-Klasse“ genannt, oder „classObj“. Die super funktioniert nur für die "neuen Stil" -Klassen. See this question for further information about this.