如何判断python变量是字符串还是列表?

时间:2009-05-07 18:53:27

标签: python list duck-typing

我有一个例程,它将一个字符串列表作为参数,但我想支持传入一个字符串并将其转换为一个字符串列表。例如:

def func( files ):
    for f in files:
        doSomethingWithFile( f )

func( ['file1','file2','file3'] )

func( 'file1' ) # should be treated like ['file1']

我的函数如何判断字符串或​​列表是否已传入?我知道有一个type函数,但是有更“pythonic”的方法吗?

8 个答案:

答案 0 :(得分:43)

isinstance(your_var, basestring)

答案 1 :(得分:37)

嗯,关于检查类型没什么特别的。话虽如此,如果你愿意给呼叫者带来一点小负担:

def func( *files ):
    for f in files:
         doSomethingWithFile( f )

func( *['file1','file2','file3'] ) #Is treated like func('file1','file2','file3')
func( 'file1' )

我认为这更像是pythonic,因为“明确比隐含更好”。当输入已经是列表形式时,至少在调用者方面有识别。

答案 2 :(得分:32)

就个人而言,我并不喜欢这种行为 - 它会干扰鸭子打字。有人可能会说它不遵守“明确比隐含更好”的口头禅。为什么不使用varargs语法:

def func( *files ):
    for f in files:
        doSomethingWithFile( f )

func( 'file1', 'file2', 'file3' )
func( 'file1' )
func( *listOfFiles )

答案 3 :(得分:16)

我想说Python最常用的方法是让用户总是传递一个列表,即使其中只有一个项目。很明显func()可以获取文件列表

def func(files):
    for cur_file in files:
        blah(cur_file)

func(['file1'])

正如Dave建议的那样,你可以使用func(*files)语法,但我从不喜欢这个功能,并且它似乎更明确(“显式比隐式更好”)只需要一个列表。它还将您的特殊情况(使用单个文件调用func)转换为默认情况,因为现在您必须使用额外的语法来使用列表调用func ..

如果您确实想要将参数设为字符串的特殊情况,请使用isinstance() builtin,并与basestringstr()unicode()进行比较来源于)例如:

def func(files):
    if isinstance(files, basestring):
        doSomethingWithASingleFile(files)
    else:
        for f in files:
            doSomethingWithFile(f)

真的,我建议只需要一个列表,即使只有一个文件(毕竟,它只需要两个额外的字符!)

答案 4 :(得分:11)

if hasattr(f, 'lower'): print "I'm string like"

答案 5 :(得分:11)

def func(files):
    for f in files if not isinstance(files, basestring) else [files]:
        doSomethingWithFile(f)

func(['file1', 'file2', 'file3'])

func('file1')

答案 6 :(得分:6)

如果您对呼叫者有更多控制权,那么其他答案之一就更好了。在我的情况下,我没有那么奢侈,所以我决定采用以下解决方案(注意事项):

def islistlike(v):
   """Return True if v is a non-string sequence and is iterable. Note that
   not all objects with getitem() have the iterable attribute"""
   if hasattr(v, '__iter__') and not isinstance(v, basestring):
       return True
   else:
       #This will happen for most atomic types like numbers and strings
       return False

此方法适用于您处理符合上述条件的已知类似列表类型的情况。但是有些序列类型会被遗漏。

答案 7 :(得分:3)

Varargs对我来说很困惑,所以我在Python中测试它以便为自己清理它。

首先,varargs的PEP是here

这是一个示例程序,基于Dave和David Berger的两个答案,然后是输出,只是为了澄清。

def func( *files ):
    print files
    for f in files:
        print( f )

if __name__ == '__main__':
    func( *['file1','file2','file3'] ) #Is treated like func('file1','file2','file3')
    func( 'onestring' )
    func( 'thing1','thing2','thing3' )
    func( ['stuff1','stuff2','stuff3'] )

结果输出;

('file1', 'file2', 'file3')
file1
file2
file3
('onestring',)
onestring
('thing1', 'thing2', 'thing3')
thing1
thing2
thing3
(['stuff1', 'stuff2', 'stuff3'],)
['stuff1', 'stuff2', 'stuff3']

希望这对其他人有帮助。