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

时间:2018-08-08 00:27:31

标签: python string list

我有一个调用REST API的函数。参数之一是逗号分隔的名称列表。要生成它,我这样做:

','.join(names)

但是,我还想允许用户提供一个名称。问题是,例如,如果names = ERII会导致['E', 'R', 'I', 'I'],但我需要改为['ERII']

现在,我可以强制用户输入仅包含一个值(names=['ERRI']names=('ERII',)的列表。我希望允许用户提供单个String。不用if else语句检查提供的值是否为Iterable的语句吗?

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

3 个答案:

答案 0 :(得分:2)

可以是事物或可迭代的事物或事物是代码气味的参数。如果事情是字符串,情况就更糟了,因为字符串是可迭代的,甚至是序列(因此,对isinstance(names, Iterable)的测试将做错事情)。

Python stdlib确实有一些这样的情况-最臭名昭著的是str.__mod__-但是大多数情况都朝着另一个方向犯错,显式地需要一个元组而不是任何可迭代的,并且大多数被认为是错误,或者至少是今天不会添加到该语言中的内容。有时候,它仍然是最好的答案,但是闻起来应该让您在这样做之前先思考一下。

我不确定您的用例是什么,但是我怀疑这样会更好:

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]

但是,如果最好的设计确实是字符串或字符串(非字符串)可迭代的字符串,或字符串或字符串的元组,则实现此目的的标准方法是类型切换。它可能看起来有些丑陋,但它引起您注意的是您确实在做自己正在做的事情,并且它是最惯用的方式。

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

答案 1 :(得分:1)

我允许列表和单个字符串作为参数。另外,我认为if / else解决方案没有任何问题,除了您可以直接检查参数是否为invisible(lapply(pkg, function(x) { if (!nzchar(system.file(package=x))) install.packages(x) library(x, character.only=TRUE) })) 类的实例(而不是检查参数是否可迭代)之外:

str

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

答案 2 :(得分:0)

使用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)

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

name = 'Eric'
name1 = 'Alice John'
namelist = ['Alice', 'Elsa', 'George']

应用此功能:

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

获取:

['Eric']

['爱丽丝,约翰']

['Alice,Elsa,George']