Python,允许将单个字符串和字符串列表传递给函数

2024-10-01 13:27:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个调用restapi的函数。其中一个参数是以逗号分隔的名称列表。要生成它,我要执行以下操作:

','.join(names)

但是,我也希望允许用户提供一个名称。问题是如果names = ERII,例如,它会导致['E', 'R', 'I', 'I'],但我需要它是['ERII']。在

现在,我可以强制用户输入一个只有一个值的列表(names=['ERRI']names=('ERII',))。我希望允许用户提供一个字符串。如果不使用if else语句检查所提供的值是否是Iterable,有没有一种聪明的方法可以做到这一点?在

同样,我不确定这里的最佳实践是什么,强制提供一个列表,还是允许一个字符串?在


Tags: 函数字符串用户名称restapi列表参数if
3条回答

我允许list和single string作为参数。另外,我认为if/else解决方案没有任何问题,只是可以直接检查参数是否是str类的实例(而不是检查参数是否可读取):

def foo(arg1):
    if isinstance(arg1, str):
        print("It's a string!")
    else:
        print("It's not a string!")

如果检查参数是否是iterable时要小心-字符串和列表都是iterable。在

使用isinstance()标识输入类型可以提供一种解决方案:

def generate_names(input_term):
    output_list = []
    if isinstance(input_term,str):
        output_list.append(','.join(input_term.split()))
    elif isinstance(input_term,list):
        output_list.append(','.join(input_term))
    else:
        print('Please provide a string or a list.')
    return(output_list)

这将允许您输入列表、单个名称的字符串以及包含多个名称的字符串(用空格分隔):

^{pr2}$

应用此函数:

print(generate_names(name))
print(generate_names(name1))
print(generate_names(namelist))

获取:

['Eric']

[爱丽丝,约翰]

[爱丽丝,艾尔莎,乔治']

参数可以是thing或iterable,也可以是代码气味。当事情是一个字符串时,情况会更糟,因为字符串是一个iterable,甚至是一个序列(因此您对isinstance(names, Iterable)的测试会做错误的事情)。在

Python stdlib确实有一些最臭名昭著的例子,str.__mod__-但是大多数错误都是相反的,显式地需要一个元组而不是任何iterable,并且它们中的大多数被认为是错误的,或者至少是今天不会添加到语言中的东西。有时候,这仍然是最好的答案,但气味应该让你在做之前思考。在

我不知道您的具体用例是什么,但我想这会更好:

def spam(*names):
    namestr = ','.join(names)
    dostuff(namestr)

现在用户可以这样称呼它:

^{pr2}$

或者,如果他们碰巧有一张单子,那还是很容易的:

spam(*ingredients)

如果这不合适,另一个选择是关键字,甚至可能是仅关键字的参数:

def spam(*, name=None, names=None):
    if name and names:
        raise TypeError('Not both!')
    if not names: names = [name]

但是,如果最好的设计真的是一个字符串或一个(非字符串)iterable字符串,或者一个字符串或一个字符串元组,那么标准的方法就是类型切换。它可能看起来有点难看,但它提醒人们注意,你正在做的正是你正在做的事情,而且它以最惯用的方式来做。在

def spam(names):
    if isinstance(names, str):
        names = [names]
    dostuff(names)

相关问题 更多 >