Gra*_*row 61 python duck-typing list
我有一个例程,它将一个字符串列表作为参数,但我想支持传入一个字符串并将其转换为一个字符串列表.例如:
def func( files ):
for f in files:
doSomethingWithFile( f )
func( ['file1','file2','file3'] )
func( 'file1' ) # should be treated like ['file1']
Run Code Online (Sandbox Code Playgroud)
我的函数如何判断字符串或列表是否已传入?我知道有一个type
功能,但是有更"pythonic"的方式吗?
Aym*_*ieh 43
isinstance(your_var, basestring)
Run Code Online (Sandbox Code Playgroud)
Dav*_*ger 37
好吧,关于检查类型没什么特别的.话虽如此,如果你愿意给呼叫者带来一点小负担:
def func( *files ):
for f in files:
doSomethingWithFile( f )
func( *['file1','file2','file3'] ) #Is treated like func('file1','file2','file3')
func( 'file1' )
Run Code Online (Sandbox Code Playgroud)
我认为这更像是pythonic,因为"明确比隐含更好".当输入已经是列表形式时,至少对呼叫者的部分进行识别.
Dav*_*ave 32
就个人而言,我并不喜欢这种行为 - 它会干扰鸭子打字.有人可能会说它不遵守"明确比隐含更好"的口头禅.为什么不使用varargs语法:
def func( *files ):
for f in files:
doSomethingWithFile( f )
func( 'file1', 'file2', 'file3' )
func( 'file1' )
func( *listOfFiles )
Run Code Online (Sandbox Code Playgroud)
dbr*_*dbr 16
我会说Python最常用的方法是让用户总是传递一个列表,即使其中只有一个项目.这使得显而易见的是func()
可以获取文件列表
def func(files):
for cur_file in files:
blah(cur_file)
func(['file1'])
Run Code Online (Sandbox Code Playgroud)
正如Dave建议的那样,你可以使用func(*files)
语法,但我从不喜欢这个功能,并且它似乎更明确("显式优于隐式")来简单地需要一个列表.它也将你的特殊情况(func
使用单个文件调用)转换为默认情况,因为现在你必须使用额外的语法来调用func
列表.
如果你想使一个特殊情况下的参数是一个字符串,可使用isinstance()
内置的,并比较basestring
(两者str()
并unicode()
从派生),例如:
def func(files):
if isinstance(files, basestring):
doSomethingWithASingleFile(files)
else:
for f in files:
doSomethingWithFile(f)
Run Code Online (Sandbox Code Playgroud)
真的,我建议只需要一个列表,即使只有一个文件(毕竟,它只需要两个额外的字符!)
lim*_*der 11
if hasattr(f, 'lower'): print "I'm string like"
Run Code Online (Sandbox Code Playgroud)
jfs*_*jfs 11
def func(files):
for f in files if not isinstance(files, basestring) else [files]:
doSomethingWithFile(f)
func(['file1', 'file2', 'file3'])
func('file1')
Run Code Online (Sandbox Code Playgroud)
如果您对呼叫者有更多控制权,那么其他答案之一就更好了.在我的情况下,我没有那么奢侈,所以我决定采用以下解决方案(注意事项):
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
Run Code Online (Sandbox Code Playgroud)
这种方法适用于您处理符合上述条件的已知类似列表类型的情况.但是会遗漏一些序列类型.