2013-06-12 42 views
7

我試圖實現自己的DailyLogFilePython:爲什麼從超類沒有看到的方法?

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) 

版本,但它看起來像我錯過一個基本的Python子類化進程的...因爲我得到這個錯誤:

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' 

,所以我需要這樣喜歡Writerotate方法明確添加並定義其他方法:

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我認爲這將是從基礎母親班正確繼承。請注意,我什麼也不做,只調用「超級」,

請有人可以解釋爲什麼我錯了我的第一個想法,它沒有必要添加寫入方法?

有沒有辦法對我的NDailyLogFile中的Python說,它應該擁有所有的方法DailyLogFile,而不是直接從它的母類中定義?這樣它可以防止這個國王的錯誤_sync(klass, klass.__dict__[methodName],並避免指定excplicitly?

(原DailyLogFile的代碼,啓發了我從扭曲的源採取這裏https://github.com/tzuryby/freespeech/blob/master/twisted/python/logfile.py

編輯:關於使用super,我得到:

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

所以不會使用它。我的經驗是這樣的......我必須明確地錯過了一些東西

+1

從面向對象的角度來看,你做得很對,除非你不想重寫所有的方法。你應該真的使用'超級'。 問題是'threadable.py'對那個OOP的東西不是很友好,因爲拋出一個錯誤的那一行檢查*那個特定類中的'write'的存在,但不是它的祖先。我沒有'扭曲'的經驗,所以不知道如何克服這一點。也許在互聯網上的某個地方有一些指南? – J0HN

+0

好的,謝謝你的評論。我不知道現在是否有更好的答案。但你必須提供一個良好的一部分:) – user2468222

+0

我覺得愚蠢的,可能是錯的方式來實現什麼是你想要做的是,以取代'克拉斯.__字典__ [方法名]'和'GETATTR(克拉斯,方法名)'的'螺.py'。最有可能的是它不會工作。這是一個扭曲的補丁。它可能會破壞特定用例之外的某些東西。因此,請嘗試將它作爲概念證明,如果它真的起作用 - 建議將它作爲通過列表或票據跟蹤器扭轉的補丁或用於利用開發的任何補丁。並且不要忘記在這裏張貼一些東西,所以我會知道它是否有幫助:) – J0HN

回答

2

我敢說twisted/python/threadable.py代碼有一個bug。 __dict__僅返回本地屬性,而不是繼承的屬性。 Otherposts說要使用dir()inspect.getmembers()來獲取它們。

好消息是,你的第一個想法是正確的,即write方法是繼承的。壞消息是Twisted不能識別繼承的方法,所以你必須自己編寫它們。

+0

'dir'將返回一個東西屬性和方法列表,但不是方法本身。 'inspect.getmembers'返回結構元素('name','value')的列表,因此可以找到一個方法,但比使用'getattr'困難。 – J0HN

+0

所以我可以明確從子類中添加它們而不必定義它們?我不確定在這裏得到關於如何使用'dir'或'inspect.getmembers()'這一點。 – user2468222

+0

@ user2468222無論如何,你將不得不修補'threadable.py',但以比getattr'更多的方式進行修改 – J0HN

3

有一個解決辦法,只是做:

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

這裏有一個問題,你使用的是類,而不實例化它。此解決方法適用,因爲您正在強制在實例化之前更改類屬性。

另一個重要的評論是,對於DailyLogFile的子類,命令super不起作用,因爲DailyLogFile是所謂的「舊式樣類」或「classobj」。 super只適用於「新風格」類。 See this question for further information about this

相關問題