需要在python中缩小我的大型if-elif语句

Need to shrink my large if elif statement in python

我试着看看是否有一个更有效的方法来写if-elif语句。编写API以根据调用类的参数数目生成URL。

对于EX:

1
2
3
4
5
6
7
8
9
10
11
def Cars(self, model=null, color=null, miles=null)

    if model == null and color == null and miles ==null:
        url = cars/
    elif model != null and color == null and miles ==null:
        url = cars/model=%s)% model
    elif model != null and color != null and miles ==null:
        url = cars/model=%s/color=%s)% model, color
    else url = someting

    return url

我有10个以上的参数,不想用所有的组合编写那么多的elif语句。


这些属性看起来不相互依赖;分别处理每个属性:

1
2
3
4
5
6
7
8
9
10
11
def cars(self, model=None, color=None, miles=None)
    url ="cars"

    if model is not None:
        url +="/model=%s" % (model,)
    if color is not None:
        url +="/color=%s" % (color,)
    if miles is not None:
        url +="/miles=%s" % (miles,)

    return url

这将导致您认识到您可能希望接受任意关键字参数,并检查特定集合的存在:

1
2
3
4
5
6
def cars(self, **kwargs):
    url ="cars"
    for kw in ["model","color","miles"]:
        if kwargs.get(kw) is not None:
            url +="/%s=%s" % (kw, kwargs[kw])
    return url

这忽略了您正在构建的字符串实际上是否是有效的URL的问题。


像切普纳的回答(以及评论中的其他回答)一样,我的想法是使用关键字参数。但是,我的方法不是每次通过循环使用url += ...,而是将参数附加到列表中,然后在创建参数列表后使用.join()创建最终字符串。这样我就不必担心是否正确地格式化了字符串;我可以让Python来解决这个问题。

我只发布这个来演示使用相同起点的替代方法。

1
2
3
4
5
6
7
8
9
10
def cars(**kwargs):  # If using as part of a class, would be cars(self, **kwargs)
    params = []
    for key in kwargs.keys():
        # Append `key=value` to `params`.
        if kwargs.get(key):
            params.append('{!s}={!s}'.format(key, kwargs[key]))
    url = '/cars?{!s}'.format('&'.join(params))
    return url

print(cars(make='Ford', model='Taurus', year=2000, colors='white'))


如果只是对URL进行模式化,其中每个参数都为URL提供一个子字符串,则可以这样做:

1
2
3
4
5
6
7
url = 'http://foo.com/'
if model is not None:
    url += 'model={}'.format(model)
if color is not None:
    url += 'color={}'.format(model)
if miles is not None:
    url += 'miles={0:.1f}'.format(model)

如果每个参数不需要任何自定义格式,则可以将所有格式折叠为:

1
2
3
url = 'http://foo.com/'
for parameter in ['model', 'color', 'miles']:
    url += '{}={}'.format(parameter, locals()[parameter])

忽略代码中的所有错误…如何:

1
2
3
4
5
6
url ="cars"
if model:
    url +="/model={}".format(model)
if color:
    url +="/color={}".format(color)
if ...


你可以这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
def Cars(self, model=null, color=null, miles=null)

    url ="cars/"
    if ( model ) :
        url +="/models=%s" % model

    if ( color ) :
        url +="/color=%s" % color

    if ( miles ) :
        url +="/miles=%s" % miles

    return url

这样写的话,你就不用使用组合数学了。在您的代码中,您将有9个if..else语句,这里只有3个。