我正在为FFmpeg编写OOP样式的Python包装器。我创建了多个编解码器类的概念,每个类都有自己的实例变量集。例如,AACCodec类可能具有一个cutoff_frequency
实例变量,例如:
class AACCodec(Codec):
def __init__(self, **kwargs):
self.cutoff_frequency = 20000
FLAC编解码器类可能具有compression_ratio
实例变量,例如:
class FLACCodec(Codec):
def __init__(self, **kwargs):
self.compression_ratio = 0.78
基本上,我的代码中的其他地方(在ffmpeg.py
中,我希望能够通过进行单个调用来创建正确的编解码器对象,例如:
import ffcodecs
newCodec = somefunctioncall('aac', 'key1'=value1, 'key2'=value2)
我考虑的实现方式是在ffcodecs.py
中使用一个函数,该函数根据输入字符串返回编解码器对象:
def getCodec(name, **kwargs):
codecObjects = {
'aac' : AACCodec(**kwargs),
'ogg' : OGGCodec(**kwargs),
'flac': FLACCodec(**kwargs)
}
return codecObjects[name]
问题在于,每当我调用getCodec()
时,它都会在声明codecObjects
时创建每个编解码器的实例。我在每个编解码器__init__
中都有逻辑,以检查**kwargs
是否匹配对象的实例变量(self.cutoff_frequency, self.compression_ratio
等),如果不匹配则报错。
在一次调用中实例化正确对象并且仅正确对象的最Python方式是什么?
一种解决方案是仅具有一组if
/ else if
语句来匹配每个编解码器字符串并相应地返回每个对象,但是如果我最终维护了一堆不同的编解码器,我不会每次实例化一个新对象时,都不需要一百条if/else
语句。
必须有一种更优雅的方法。
答案 0 :(得分:1)
这里有几个问题。
这是最直接的:
这个问题是,每当我调用getCodec()时,它都会创建一个 声明codecObjects时,每个编解码器的实例。
更改函数,使其不实例化所有类:
def getCodec(name, **kwargs):
codecClasses = {
'aac' : AACCodec,
'ogg' : OGGCodec,
'flac': FLACCodec
}
return codecClasses[name](**kwargs)
这是最好的方法吗?好吧,有些事情我会有所不同...
例如,我将明确定义参数:
def __init__(self, cutoff_frequency=20000):
self.cutoff_frequency = cutoff_frequency
您仍然可以在**kwargs
中使用getCodec
。
另一方面,我根本不明白为什么您需要getCodec
。最后,您必须使用特定于当前编解码器的参数来调用它,因此您已经必须知道要实例化哪个编解码器。因此,您可以明确地做到这一点。
答案 1 :(得分:0)
也许不是最好的,但您可以做到
def getCodec(name, **kwargs):
codecObjects = {
'aac' : AACCodec,
'ogg' : OGGCodec,
'flac': FLACCodec
}
return codeObjects[name](**kwargs)
毕竟,您试图将一个字符串映射到一个类,但只需要实例化一个