在 python 中覆盖 class __init__ 的方法

Way to override a class __init__ in python

当我调用 mic.openTheMic(record_seconds = 10) 时,我想使用所有 class 默认值,或者如果我想更改(一个或多个)参数,则只有包括一个,例如 record_seconds = 10 的这种情况。有办法吗?

class myAudio(object):
    def __init__(self, chunk = 1024, format = pyaudio.paInt16, channels = 1,
        rate = 41000, record_seconds = 5):
        self.p = pyaudio.PyAudio()
        self.CHUNK = chunk
        self.FORMAT = format
        self.CHANNELS = channels
        self.RATE = rate
        self.RECORD_SECONDS = record_seconds


    def openTheMic(chunk = 1024, format = pyaudio.paInt16, channels = 1,
            rate = 41000, record_seconds = 5):

        q = myAudio(chunk = 1024, format = pyaudio.paInt16, channels = 1,
            rate = 41000, record_seconds = 5)

        q = myAudio()

        stream = q.p.open(format = q.FORMAT,
        channels = q.CHANNELS,
        rate = q.RATE,
        input = True,
        output = True,
        frames_per_buffer = q.CHUNK)

        print ("***mic is open***")

        for i in range(0, q.RATE / q.CHUNK * q.RECORD_SECONDS):
             data = stream.read(q.CHUNK)

if __name__ == '__main__':
    mic = myAudio()
    mic.openTheMic(record_seconds = 10)

像(未测试)这样的东西怎么样:

class myAudio(object):
    _map = {
        'chunk': 'CHUNK',
        'fmt': 'FORMAT',
        'channels': 'CHANNELS',
        'rate': 'RATE',
        'record_seconds': 'RECORD_SECONDS',
    }

    def __init__(self, chunk=1024, fmt=pyaudio.paInt16, channels=1, rate=41000, record_seconds=5):
        self.p = pyaudio.PyAudio()
        self.CHUNK = chunk
        self.FORMAT = fmt
        self.CHANNELS = channels
        self.RATE = rate
        self.RECORD_SECONDS = record_seconds


    def openTheMic(self, **kwargs):
        for (k,v) in kwargs.iteritems():
            setattr(self, myAudio.__map[k], v)

        stream = self.p.open(
            format = self.FORMAT,
            channels = self.CHANNELS,
            rate = self.RATE,
            input = True,
            output = True,
            frames_per_buffer = self.CHUNK
        )

        print ("***mic is open***")

        for i in range(0, self.RATE / q.CHUNK * self.RECORD_SECONDS):
             data = stream.read(self.CHUNK)

if __name__ == '__main__':
    mic = myAudio()
    mic.openTheMic(record_seconds = 10)

请注意,我将 format 更改为 fmt 以避免隐藏内置函数。此外,调用 openTheMic 会永久 更改实例属性值。如果你不想这样,也许是这样的:

class myAudio(object):

    def __init__(self, chunk=1024, fmt=pyaudio.paInt16, channels=1, rate=41000, record_seconds=5):
        self.p = pyaudio.PyAudio()
        self.CHUNK = chunk
        self.FORMAT = fmt
        self.CHANNELS = channels
        self.RATE = rate
        self.RECORD_SECONDS = record_seconds


    def openTheMic(self, **kwargs):
        _chunk          = kwargs.get('chunk',          self.CHUNK)
        _format         = kwargs.get('fmt',            self.FORMAT)
        _channels       = kwargs.get('channels',       self.CHANNELS)
        _rate           = kwargs.get('rate',           self.RATE)
        _record_seconds = kwargs.get('record_seconds', self.RECORD_SECONDS)

        stream = self.p.open(
            format            = _format,
            channels          = _channels,
            rate              = _rate,
            input             = True,
            output            = True,
            frames_per_buffer = _chunk
        )

        print ("***mic is open***")

        for i in range(0, _rate / _chunk * _record_seconds):
             data = stream.read(_chunk)

if __name__ == '__main__':
    mic = myAudio()
    mic.openTheMic(record_seconds = 10)