python:为什么没有看到来自超级类的方法?

Python : why a method from super class not seen?

我正在尝试实现我自己版本的DailyLogFile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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子类化过程的一个基本步骤……当我得到这个错误时:

1
2
3
4
5
6
7
8
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方法,如下所示:

1
2
3
4
5
6
7
8
9
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)

而我认为它将正确地继承自母类。注意我什么都不做,只叫"超级",

请有人解释一下为什么我的第一个想法是不需要添加写方法是错误的吗?

在我的ndailyLogFile中,有没有一种方法可以告诉python它应该拥有所有不直接从其母类定义的dailyLogFile方法?所以它可以防止这个错误之王_sync(klass, klass.__dict__[methodName],并且避免详细说明?

(DailyLogFile的原始代码激发了我的灵感,它取自于Twisted的源代码:https://github.com/tzuryby/freespeech/blob/master/twisted/python/logfile.py)

编辑:关于使用super,我得到:

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

所以不会使用它。我的想法是对的…我肯定错过了什么


有一个解决方法,只要:

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

这里有一个问题,您在使用类时没有实例化它。这种解决方法之所以有效,是因为您在实例化之前强制更改类属性。

另一个重要的评论是,对于DailyLogFile的一个子类,命令super将不起作用,因为DailyLogFile是所谓的"旧式类",或"classobj"。super只适用于"新风格"类。有关此问题的详细信息,请参阅此问题。


我敢说,twisted/python/threadable.py代码中有一个bug。__dict__只返回局部属性,不返回继承的属性。其他的帖子说用dir()或者inspect.getmembers()来获取它们。

好消息是,您对继承write方法的第一个想法是正确的。坏消息是Twisted无法识别继承的方法,因此您必须自己编写它们。