我怎么知道一个pythonvariables是一个string还是一个列表?

我有一个例程,将string列表作为参数,但我想支持传递单个string并将其转换为一个string的列表。 例如:

def func( files ): for f in files: doSomethingWithFile( f ) func( ['file1','file2','file3'] ) func( 'file1' ) # should be treated like ['file1'] 

我的函数如何判断一个string还是一个列表已经被传入? 我知道有一个type函数,但是有一个“更pythonic”的方式?

那么,检查types没有任何不妥协的地方。 话虽如此,如果你愿意给调用者带来一点负担:

 def func( *files ): for f in files: doSomethingWithFile( f ) func( *['file1','file2','file3'] ) #Is treated like func('file1','file2','file3') func( 'file1' ) 

我认为这是更为pythonic在“明确优于暗示”。 当input已经是列表forms的时候,至less在调用者方面有一个确认。

 isinstance(your_var, basestring) 

就个人而言,我不太喜欢这种行为 – 它干扰鸭子打字。 有人可能会争辩说,它不服从“明显优于暗示”的口头禅。 为什么不使用可变参数语法:

 def func( *files ): for f in files: doSomethingWithFile( f ) func( 'file1', 'file2', 'file3' ) func( 'file1' ) func( *listOfFiles ) 

我想说的最python的方式是让用户总是通过一个列表,即使只有一个项目。 它使真正明显的func()可以获取文件列表

 def func(files): for cur_file in files: blah(cur_file) func(['file1']) 

正如Dave所build议的,你可以使用func(*files)语法,但是我从来不喜欢这个特性,而且看起来更加明确(“显式比隐式更好”)来简单地需要一个列表。 它也将你的特殊情况(调用一个单一文件的func )变成默认情况,因为现在你必须使用额外的语法来调用一个列表的func

如果你想为一个参数作为一个string做一个特殊情况,使用isinstance()内build basestring ,并且与basestring (其中str()unicode()是从派生而来的)进行比较,例如:

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

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

 def func(files): for f in files if not isinstance(files, basestring) else [files]: doSomethingWithFile(f) func(['file1', 'file2', 'file3']) func('file1') 
 if hasattr(f, 'lower'): print "I'm string like" 

如果你对呼叫者有更多的控制权,那么其他的答案就更好了。 我没有那么奢侈,所以我决定采取以下解决scheme(注意事项):

 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 

这种方法适用于您正在处理符合上述标准的一组列表types的情况。 一些序列types将被错过。

Varargs对我感到困惑,所以我用Python进行了testing,为自己解决了这个问题。

首先是可变参数的PEP 在这里 。

下面是示例程序,基于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'] 

希望这对其他人有帮助。