基于用户输入实例化对象的Python方法

时间:2018-07-26 20:23:33

标签: python class oop object

我正在为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语句。

必须有一种更优雅的方法。

2 个答案:

答案 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)

毕竟,您试图将一个字符串映射到一个类,但只需要实例化一个