Python中的多重继承(特定于问题)

2024-09-28 01:30:27 发布

您现在位置:Python中文网/ 问答频道 /正文

这里有人能确定为什么在下面这个例子的底部引发TypeError吗?在

>>> import threading
>>> class SessionManager(threading.Thread, threading._RLock, dict):

    UPDATE = 60 * 60

    def run(self):
        while True:
            time.sleep(self.UPDATE)
            with self:
                for key in tuple(self):
                    if not self[key]:
                        del self[key]

    def __getitem__(self, key):
        session = super()[key]
        session.wakeup()
        return session

>>> SM = SessionManager()
>>> SM.daemon = True
>>> SM.start()
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    SM.start()
TypeError: unhashable type: 'SessionManager'
>>> 

编辑:

下面是上述模块的完成版本。它在VerseMatch程序中使用。在

^{pr2}$

Tags: keyinimportselftruesessiondefupdate
2条回答

尽管Alex对这个问题进行了深入的诊断,但我强烈主张,在这种情况下,您不应该将inherit from dict进行乘法继承(或者一般情况下,对于这种情况),尽管从它派生子类并自动继承所有dict行为似乎很方便,但是dict(以及一般的内置类型)通常都会受到快捷方式的影响内部。例如,“get”方法不会调用已修改的__getitem__,即使它确实获取了项:

>>> class MyDict(dict):
...     def __getitem__(self, key):
...         print("in __getitem__(%r)" % (key,))
...         return super(MyDict, self).__getitem__(key)
... 
>>> d = MyDict({'a': 'b', 'c': 'd'})
>>> d['a']
in __getitem__('a')
'b'
>>> d.get('c')
'd'
>>>

(这样的案例不胜枚举。)

此外,涉及内置类型的多重继承要求所有类型的实例在内存中的布局都是兼容的。碰巧,threading.Threadthreading._Rlock是Python类(这意味着它们有一个非常简单的内存布局,与dict兼容),但是如果将来改变了这一点,或者您想包含其他类型,它就会失败。在

这真是个坏主意。在

问题来自threading.py,可以更简单地再现如下:

>>> import threading
>>> class SessionManager(threading.Thread, threading._RLock, dict): pass
... 
>>> s = SessionManager()
>>> s.start()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py", line 469, in start
    _limbo[self] = self
TypeError: unhashable type: 'SessionManager'

您可以研究threading.py,以确切地了解为什么线程对象需要是散列的,但是修复也很简单:只需覆盖另外两个方法

^{pr2}$

这使得类的实例可以散列。在

相关问题 更多 >

    热门问题