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

Python,允许将单个字符串和字符串列表传递给函数,python,string,list,Python,String,List,我有一个调用RESTAPI的函数。其中一个参数是以逗号分隔的名称列表。要生成它,我需要执行以下操作: ','.join(names) 但是,我还希望允许用户提供单个名称。问题是,例如,如果names=ERII,它会导致['E','R','I','I'],但我需要它改为['ERII'] 现在,我可以强制用户输入一个只有一个值的列表(names=['ERRI']或names=('ERII',)。我更愿意允许用户提供一个字符串。如果不使用if-else语句检查所提供的值是否为Iterable,有没有

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

','.join(names)
但是,我还希望允许用户提供单个名称。问题是,例如,如果
names=ERII
,它会导致
['E','R','I','I']
,但我需要它改为
['ERII']

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


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

我将允许列表和单个字符串作为参数。此外,我认为if/else解决方案没有任何问题,只是您可以直接检查参数是否是
str
类的实例(而不是检查参数是否可编辑):


如果检查参数是否可iterable,请小心-字符串和列表都可iterable。

我允许列表和单个字符串作为参数。此外,我认为if/else解决方案没有任何问题,只是可以直接检查参数是否是
str
类的实例(而不是检查参数是否可编辑):


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

可以是thing或iterable的参数,或者thing是代码气味。如果thing是字符串,则情况更糟,因为字符串是iterable,甚至是序列(因此对
的测试是instance(name,iterable)
会做错事)

Python stdlib确实存在一些这样的情况,最臭名昭著的是,
str.\uuuuu mod\uuuuuu
——但大多数情况都会出现相反的错误,明确要求使用元组而不是任何iterable,并且大多数情况被认为是错误,或者至少是今天无法添加到语言中的东西。有时这仍然是最好的答案,但是气味会让你在做之前思考

我不知道您的用例是什么,但我怀疑这会更好:

def spam(*names):
    namestr = ','.join(names)
    dostuff(namestr)
现在用户可以这样称呼它:

spam('eggs')
spam('eggs', 'cheese', 'beans')
或者,如果他们碰巧有一个列表,这仍然很容易:

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)

参数可以是一个对象,也可以是一个iterable,或者对象是一种代码味道。如果对象是一个字符串,则情况更糟,因为字符串是一个iterable,甚至是一个序列(因此对
isinstance(names,iterable)
的测试将执行错误的操作)

Python stdlib确实存在一些这样的情况,最臭名昭著的是,
str.\uuuuu mod\uuuuuu
——但大多数情况都会出现相反的错误,明确要求使用元组而不是任何iterable,并且大多数情况被认为是错误,或者至少是今天无法添加到语言中的东西。有时这仍然是最好的答案,但是气味会让你在做之前思考

我不知道您的用例是什么,但我怀疑这会更好:

def spam(*names):
    namestr = ','.join(names)
    dostuff(namestr)
现在用户可以这样称呼它:

spam('eggs')
spam('eggs', 'cheese', 'beans')
或者,如果他们碰巧有一个列表,这仍然很容易:

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)
使用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)
这将允许您输入列表、单个名称的字符串以及包含多个名称的字符串(用空格分隔):

应用此功能:

print(generate_names(name))
print(generate_names(name1))
print(generate_names(namelist))
获取:

['Eric']

['Alice,John']

['Alice,Elsa,George']

使用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)
这将允许您输入列表、单个名称的字符串以及包含多个名称的字符串(用空格分隔):

应用此功能:

print(generate_names(name))
print(generate_names(name1))
print(generate_names(namelist))
获取:

['Eric']

['Alice,John']


['Alice,Elsa,George']

@Carcigenicate,我没有变量
名称
。在参数中使用
*名称
怎么样?这样用户就可以发送一个或五个名称给你,而不需要括号,或者,如果他手头有一个列表,他就可以使用
*lst
将其显示给你。@Carcigenicate,我没有变量
名称
。使用
*名称怎么样s
在参数中?然后用户可以发送一个或五个名称,而不需要括号,或者,如果他手头有列表,他可以向您发送。是的,我想这就是我现在要做的!您是对的,检查Iterable对我来说不是一个好主意:字符串是Iterable这一事实导致了我的问题首先,我想这就是我现在要做的!你是对的,检查Iterable对我来说不是个好主意:字符串是Iterable这一事实首先导致了我的问题…谢谢你的回答,我感谢关于最佳编码实践的建议。在我的具体情况下,这是我的建议函数的签名:
def get_符号(name=None,id