Python子类化问题

时间:2015-01-12 19:43:15

标签: python python-3.x subclass

我遇到了python子类的问题:

我有自己的类,Player,它扩展了在外部模块中定义的MediaPlayer类。 MediaPlayer扩展了_Ctype并实现了__new__方法。

以下是我班级的代码:

import vlc
from PyQt5.QtCore import QObject
from core import Media

class Player(vlc.MediaPlayer, QObject):
    def __new__(cls,  *args):
        return super(Player, cls).__new__(cls, *args)

    def __init__(self, *args):
        super(Player, self).__init__(self, None)

    def setMedia(self,  location=None):
        print(self)
        media = Media.Media(location)
        print("Player.setMedia")
        self.set_media(media)

当我打电话

player.setMedia([file_path]) #player is supposed to be an instance of the Player class

我收到以下错误:

AttributeError: 'MediaPlayer' object has no attribute 'setMedia'

问题似乎是当我实例化Player类时它返回一个MediaPlayer实例,因此我不能使用setMedia方法。

所以我想知道你们中是否有人知道为什么会出现这个问题以及如何解决这个问题。

感谢您阅读我的帖子。

我在Windows 8.1 64位上使用Python 3.4.2 64位。

1 个答案:

答案 0 :(得分:0)

我不完全理解vlc模块的ctypes代码,但看起来它确实不能正确支持继承。 MediaPlayer.__new__的返回值始终是MediaPlayer的实例,而不是作为cls arg传入的类型的实例。我想这是一个错误。

我不确定你是否可以直接解决这个问题。一种可能的解决方案是尝试修复__new__中返回的对象的类:

def __new__(cls,  *args):
    self = super(Player, cls).__new__(cls, *args)
    self.__class__ = cls
    return self

我不知道这是否能正常工作(或根本不能)。在使用C代码构建的对象中,__class__属性并不总是可写的,即使可以写入,也可能会破坏它。

另一个问题是第二个基本类型QObject没有得到__new__调用的MediaPlayer.__new__方法。如果QObject在那里做了什么特别的事情,那么在更改__class__变量后得到的实例可能仍然没有处于合理状态。通常你需要所有的基类来支持合作多重继承,如果你要做任何复杂的多个基础(mixins可能是一个例外),但在这种情况下,你至少有一个基础没有&# 39;甚至可以正确支持单一继承。

另一个可能更加万无一失的解决方案是放弃继承(至少对于MediaPlayer的{​​{1}}部分),只需在{{Player中创建对MediaPlayer实例的引用1}}:

__init__

如果您在其他代码中的class Player(QObject): def __init__(self, *args): super().__init__(*args) # pass args to QObject? self.media_player = MediaPlayer(*args) # and to MediaPlayer as well? def setMedia(self, location=None): print(self) media = Media.Media(location) print("Player.setMedia") self.media_player.set_media(media) 实例上调用MediaPlayer方法,则可能需要代理相关方法。