2016-05-08 51 views
1

我做了這個類:如何強制上課?

class AudioSegmentCustom(AudioSegment): 

    def fade_override(self, seg, fade_len=100): 
     seg1, seg2 = AudioSegment._sync(self, seg) 
     final = seg1[:-fade_len] 
     a_fin = seg1[-fade_len:].fade(to_gain=-120, start=0, end=float('inf')) 
     a_fin *= seg2[:fade_len] 
     return (final + a_fin) + seg2[fade_len:] 

我面臨的問題是,當我創建一些AudioSegmentCustom變量,如果我「添加」。其中,add操作返回原來的父類型= AudioSegment

因此,下面的代碼無法正常工作:

final = AudioSegmentCustom.from_mp3(mp3_src) + AudioSegment.from_mp3(mp3_other) 
final = final.fade_override(...blabla...) 

,因爲我得到:

'AudioSegment' object has no attribute 'fade_override' 

...即使我已經開始使用AudioSegmentCustom對象,但我只以AudioSegment「only」對象結束。 「強制」新創建的對象的類型的方式是什麼?

以防萬一你需要它:

class AudioSegment(object): 
    def __add__(self, arg): 
     if isinstance(arg, AudioSegment): 
      return self.append(arg, crossfade=0) 
     else: 
      return self.apply_gain(arg) 
+0

您應該包含'AudioSegment .__ add__'的代碼。 –

+0

它只是返回一個AudioSegment對象。你爲什麼需要它?無論如何,只是更新了我的問題 –

+0

因爲一種方法是調整它,以便它創建與「self」相同的類的實例。如果您不想改變它,那麼您肯定需要編寫一個單獨的'AudioSegmentCustom .__ add__'方法或在其他地方構造'AudioSegmentCustom'。 –

回答

1

貌似問題是AudioSegment._spawn()

它無條件地返回一個裸機AudioSegment實例。既然是正常的方法,您可以在AudioSegmentCustom重寫它:

def _spawn(self, data, overrides={}): 
    """ 
    Creates a new audio segment using the metadata from the current one 
    and the data passed in. Should be used whenever an AudioSegment is 
    being returned by an operation that would alters the current one, 
    since AudioSegment objects are immutable. 
    """ 
    # accept lists of data chunks 
    if isinstance(data, list): 
     data = b''.join(data) 

    # accept file-like objects 
    if hasattr(data, 'read'): 
     if hasattr(data, 'seek'): 
      data.seek(0) 
     data = data.read() 

    metadata = { 
     'sample_width': self.sample_width, 
     'frame_rate': self.frame_rate, 
     'frame_width': self.frame_width, 
     'channels': self.channels 
    } 
    metadata.update(overrides) 
    return self.__class__(data=data, metadata=metadata) 

複製粘貼&肯定不是一個很好的做法,但它的工作。

但是,請注意,它引入了不對稱性,因爲AudioSegmentCustom + AudioSegment返回AudioSegmentCustom,而AudioSegment + AudioSegmentCustom返回AudioSegment。 這個 - 更多 - 可以通過在AudioSegmentCustom中額外提供__radd__()來修復。它將在AudioSegment.__add__()之前被調用。

+1

您可以定義'__radd __()'來避免這種不對稱性:因爲[文檔](https://docs.python.org/2/reference/datamodel.html#object.__radd__)指出,在右操作數是左邊的一個子類,Python將首先調用右邊的__radd__。 –

+0

@DanielRoseman謝謝你指出。添加。 – dhke

+0

[各自更改](https://github.com/jiaaro/pydub/commit/40bd30c81e12664d849de78fcf8bd43359d16c72)已合併到pydub中,並且對於將來的版本,應該不再需要hack。 – dhke