[英]How can I tell if a python variable is a string or a list?
我有一個例程,它將一個字符串列表作為參數,但我想支持傳入一個字符串並將其轉換為一個字符串列表。 例如:
def func( files ):
for f in files:
doSomethingWithFile( f )
func( ['file1','file2','file3'] )
func( 'file1' ) # should be treated like ['file1']
我的函數如何判斷字符串或列表是否已傳入? 我知道有一個type
函數,但是有更“pythonic”的方式嗎?
isinstance(your_var, basestring)
好吧,關於檢查類型沒什么特別的。 話雖如此,如果你願意給呼叫者減輕負擔:
def func( *files ):
for f in files:
doSomethingWithFile( f )
func( *['file1','file2','file3'] ) #Is treated like func('file1','file2','file3')
func( 'file1' )
我認為這更像是pythonic,因為“明確比隱含更好”。 當輸入已經是列表形式時,至少對呼叫者的部分進行識別。
就個人而言,我並不喜歡這種行為 - 它會干擾鴨子打字。 有人可能會說它不遵守“明確比隱含更好”的口頭禪。 為什么不使用varargs語法:
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建議的那樣,您可以使用func(*files)
語法,但我從不喜歡這個功能,並且它似乎更明確(“顯式優於隱式”)只需要一個列表。 它也將你的特殊情況(用單個文件調用func
)轉換為默認情況,因為現在你必須使用額外的語法來用列表調用func
。
如果你想為參數創建一個特殊情況作為字符串,請使用isinstance()
內置 ,並與basestring
( str()
和unicode()
的派生比較,例如:
def func(files):
if isinstance(files, basestring):
doSomethingWithASingleFile(files)
else:
for f in files:
doSomethingWithFile(f)
真的,我建議只需要一個列表,即使只有一個文件(畢竟,它只需要兩個額外的字符!)
if hasattr(f, 'lower'): print "I'm string like"
def func(files):
for f in files if not isinstance(files, basestring) else [files]:
doSomethingWithFile(f)
func(['file1', 'file2', 'file3'])
func('file1')
如果您對呼叫者有更多控制權,那么其他答案之一就更好了。 在我的情況下,我沒有那么奢侈,所以我決定采用以下解決方案(注意事項):
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
這種方法適用於您處理符合上述條件的已知類似列表類型的情況。 但是會遺漏一些序列類型。
Varargs對我很困惑,所以我用Python測試它以便為自己清理它。
首先,varargs的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']
希望這對其他人有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.