我遇到了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位。
答案 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
方法,则可能需要代理相关方法。