如何强制到class?

How to force to a class?

我做了这个class:

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" 它们,add 操作 returns 其原始父类型 = 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" 对象结束。 "force"新建对象的类型有什么方法?

以备不时之需:

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

看起来问题出在 AudioSegment._spawn()

它无条件 returns 一个简单的 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 returns 和 AudioSegmentCustom,而 AudioSegment + AudioSegmentCustom returns 和 AudioSegment . 这 -- 再一次 -- 可以通过在 AudioSegmentCustom 中额外提供 __radd__() 来解决。它会在 AudioSegment.__add__().

之前被调用