如何强制到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__()
.
之前被调用
我做了这个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__()
.