2010-09-07 40 views
0

我有下面的代码清单:对象工厂产生一个或多个对象

def f(cls, value): 
    # cls is a class 
    # value is a string value 
    if cls == str: 
    pass # value is already the right type 
    elif cls == int: 
    value = int(value) 
    elif cls == C1: 
    value = C1(value) 
    elif cls == C2: 
    value = C2(value) 
    elif cls == C3 
    # in this case, we convert the string into a list of objects of class C3 
    value = C3.parse(value) 
    else 
    raise UnknownClass(repr(cls)) 
    return value 

很明显,我想喜欢的东西来替代它:

def f(cls, value) 
    return cls(value) 

不幸的是,在一些case(如果cls == C3),输入的解析结果将成为该类的对象列表,而不仅仅是一个对象。什么是一个干净的方式来处理这个问题?我可以访问所有的课程。

回答

2

如果大多数案件最好通过调用cls处理,而其他几个最好处理,否则最简单的办法是选出后者:

themap = {C3: C3.parse} 
for C in (str, C1, C2): 
    themap[C] = C 

def f(cls, value): 
    wot = themap.get(cls) 
    if wot is None: 
     raise UnknownClass(repr(cls)) 
    return wot(value) 

注意,在一根绳子上调用str是一个相当快空操作,所以它通常值得避免了有利于简化代码的特定情况下“单挑”。

+0

没有办法从X()返回X的列表而不是X,我假设? – max 2010-09-07 05:53:30

+0

@max,当你写一个'class X'时,你可以重载'X .__ new__'来返回你想要的任何东西(如果不是'X'实例,'X .__ init__'不会被调用) - 当然这可能会有严重的缺点,例如很难有一个单一的“X”实例(那么如何让实例放入该列表中?) - 这不是不可能的,但是非常不方便。 'classmethod'通常是构建“替代”构造函数的更好方法。 – 2010-09-07 13:51:19

0

这取决于你对列表做什么。这是最简单的方法:

OBJ = CLS(值)

如果类型(OBJ)==名单:

handle_list(OBJ)

回报OBJ

+0

其使用isinstance内置方法而不是使用类型的好习惯! – shahjapan 2010-09-07 07:17:16