Parent class 在 child 之前调用
Parent class called before child
我正在创建一个继承自 PySndfile 的 child class,它将包含与 PySndfile class.
相关的额外功能
但是,当使用不适用于 PySndfile class 的关键字参数初始化 child class 时,参数似乎直接发送到 parent class,完全绕过 child 的 init(即不调用打印语句,不从 kwargs 中弹出参数并且不回溯完全参考child class。
如有任何帮助,我们将不胜感激。
ClassProblem.py:
from pysndfile import PySndfile
class AudioFile(PySndfile):
def __init__(self, filename, mode, rms="123"):
print 'AudioFile init called'
self.rms = rms
super(AudioFile, self).__cinit__(
self,
filename,
mode=mode,
format=None,
channels=None,
samplerate=None
)
aa = AudioFile(
"/path/to/audio/file.wav",
'r',
rms="456",
)
产生错误:
Traceback (most recent call last):
File "ClassProblem.py", line 18, in <module>
rms="456",
File "_pysndfile.pyx", line 564, in _pysndfile.PySndfile.__cinit__ (_pysndfile.cpp:3308)
TypeError: __cinit__() got an unexpected keyword argument 'rms'
PySndfile 似乎是一个 Cython 库。我对 Cython 一无所知,但从回溯中可以看出它使用 __cinit__
而不是 __init__
。您可能应该改写该方法。
您有效地将 **kwargs
传递给 PySndfile 构造函数,但它不知道如何处理特定于您的 class 的 rms
参数。我本地没有 PySndfile 但在网上快速浏览后,我看到 pyx 构造函数如下所示:
def __cinit__(self, filename, mode='r', int format=0,
int channels=0, int samplerate=0):
这不是一个 *args, **kwargs
函数,可以接受任何参数,但它有一个固定的签名。我建议使用类似的构造函数更新 class,您可以向其中添加特定于 class:
的参数
def __init__(self, filename, mode='r', rms=0, format=0,
channels=0, samplerate=0):
然后将所有参数传递给超级构造函数(除了rms,它不理解)。
,您似乎必须覆盖 __new__
If you anticipate subclassing your extension type in Python, you may find it useful to give the cinit() method * and ** arguments so that it can accept and ignore extra arguments. Otherwise, any Python subclass which has an init() with a different signature will have to override new() [1] as well as init(), which the writer of a Python class wouldn’t expect to have to do.
我通过将此问题发布到 /r/learnpython sub-reddit
找到了答案
用户 yes_or_gnome 很好地解释了为什么我需要覆盖 __new__ class 方法以及 __init__ 方法,并提供了示例代码.
我正在创建一个继承自 PySndfile 的 child class,它将包含与 PySndfile class.
相关的额外功能但是,当使用不适用于 PySndfile class 的关键字参数初始化 child class 时,参数似乎直接发送到 parent class,完全绕过 child 的 init(即不调用打印语句,不从 kwargs 中弹出参数并且不回溯完全参考child class。
如有任何帮助,我们将不胜感激。
ClassProblem.py:
from pysndfile import PySndfile
class AudioFile(PySndfile):
def __init__(self, filename, mode, rms="123"):
print 'AudioFile init called'
self.rms = rms
super(AudioFile, self).__cinit__(
self,
filename,
mode=mode,
format=None,
channels=None,
samplerate=None
)
aa = AudioFile(
"/path/to/audio/file.wav",
'r',
rms="456",
)
产生错误:
Traceback (most recent call last):
File "ClassProblem.py", line 18, in <module>
rms="456",
File "_pysndfile.pyx", line 564, in _pysndfile.PySndfile.__cinit__ (_pysndfile.cpp:3308)
TypeError: __cinit__() got an unexpected keyword argument 'rms'
PySndfile 似乎是一个 Cython 库。我对 Cython 一无所知,但从回溯中可以看出它使用 __cinit__
而不是 __init__
。您可能应该改写该方法。
您有效地将 **kwargs
传递给 PySndfile 构造函数,但它不知道如何处理特定于您的 class 的 rms
参数。我本地没有 PySndfile 但在网上快速浏览后,我看到 pyx 构造函数如下所示:
def __cinit__(self, filename, mode='r', int format=0,
int channels=0, int samplerate=0):
这不是一个 *args, **kwargs
函数,可以接受任何参数,但它有一个固定的签名。我建议使用类似的构造函数更新 class,您可以向其中添加特定于 class:
def __init__(self, filename, mode='r', rms=0, format=0,
channels=0, samplerate=0):
然后将所有参数传递给超级构造函数(除了rms,它不理解)。
__new__
If you anticipate subclassing your extension type in Python, you may find it useful to give the cinit() method * and ** arguments so that it can accept and ignore extra arguments. Otherwise, any Python subclass which has an init() with a different signature will have to override new() [1] as well as init(), which the writer of a Python class wouldn’t expect to have to do.
我通过将此问题发布到 /r/learnpython sub-reddit
找到了答案用户 yes_or_gnome 很好地解释了为什么我需要覆盖 __new__ class 方法以及 __init__ 方法,并提供了示例代码.