pyannote源码阅读(一)

前言

读一读代码,顺便记录一下笔记。

pyannote-core源码

Segment类的设计和实现要点

from dataclasses import dataclass

@dataclass(frozen=True, order=True)
class Segment:
  start: float = 0.0
  end: float = 0.0
  
  def set_precision(ndigits: Optional[int] = None):
    global AUTO_ROUND_TIME
    global SEGMENT_PRECISION
    
  
  def __post_init__(self):
    if AUDIO_ROUND_TIME:
      object.__setattr__(self, 'start', int(self.start / SEGMENT_PRECISION + 0.5) * SEGMENT_PRECISION)
      object.__setattr__(self, 'end', int(self.end / SEGMENT_PRECISION + 0.5) * SEGMENT_PRECISION)
  
  @property
  duration(self) -> float:
    return self.end - self.start if self else 0.

dataclass装饰器

dataclass是从Python3.7版本开始,作为标准库中的模块被引入。
可以简化数据类的设计,在上面的代码中,直接定义属性并初始化。

  start: float = 0.0
  end: float = 0.0

frozen=True 创建不可变类,不允许更改属性值。

创建一个Segment对象,可以这样Segment(start=1, end=5) 或者 Segment(1, 5)

这里有一个细节,如果设置了数值经度,比如保留2位小数,但初始化时使用了三位以上的小数,要如何处理?因为使用了frozen,是无法对属性进行直接修改的。

方法是在__post_init__方法中使用如下代码:

object.__setattr__(self, 'start', int(self.start / SEGMENT_PRECISION + 0.5) * SEGMENT_PRECISION)

顾名思义,__post_init__方法在对象初始化之后调用。

  • 全局变量
    AUTO_ROUND_TIME 是否四舍五入
    SEGMENT_PRECISION 精度

迭代器方法


def __iter__(self): -> Iterator[float]:
  yield self.start
  yield self.end

通过yield实现,从而支持

segment = Segment(start, end)
start, end = segment

提供的方法

  • copy 复制一个Segment
  • contains 判读一个Segment是否包含另一个Segment
  • and 求两个Segment的交集
  • or 求两个Segment的并集
  • intersects 判断连个Segment是否相交
  • overlaps 判断一个Segment是否覆盖另一个

字符串和图形表示

def __str__(self):
  if self:
    return '[%s --> %s]' % (self._str_helper(self.start), self._str_helper(self.end))

可以把Segment(1337, 1337 + 0.42)表示为:[ 00:22:17.000 --> 00:22:17.420],very nice。

小结

这是一个非常不错的设计,在音频处理的很多场景都可以参考。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值