我想编写一个 Python 函数,它遍历输入参数的行,但可以接受字符串或类似文件的对象。有没有办法做到这一点?
def myfunc(x):
for line in x:
doSomething(line)
上面的代码适用于类似文件的对象,但不适用于字符串,我宁愿只写一个函数而不是两个,因为我的实际任务比上面的要复杂得多。
我想编写一个 Python 函数,它遍历输入参数的行,但可以接受字符串或类似文件的对象。有没有办法做到这一点?
def myfunc(x):
for line in x:
doSomething(line)
上面的代码适用于类似文件的对象,但不适用于字符串,我宁愿只写一个函数而不是两个,因为我的实际任务比上面的要复杂得多。
使用鸭子打字:
def myfunc(x):
try:
lines = x.split('\n')
except AttributeError:
lines = x
for line in lines:
doSomething(line)
如果您愿意,还可以检查类型:
def myfunc(x):
if isinstance(x, basestring): # will work in Python >=2.3, <3.x
lines = x.split('\n')
else:
lines = x
for line in lines:
doSomething(line)
您可以在这里使用大约一百万种变体try-except
def myfunc(x):
try:
x = x.splitlines(True)
except AttributeError:
pass #likely a file
for line in x:
doSomething(line)
另一个版本(稍微不那么宽松——见评论):
try:
from cStringIO import StringIO
except ImportError: #python 3
from io import StringIO
def myfunc(x):
try:
x.seek(0)
except AttributeError: #likely a string
x = StringIO(x)
for line in x:
doSomething(line)
它也适用于字符串,但它会逐个字符地迭代字符串。用户应该使用字符串列表来调用您的函数。
如果您明确希望支持传入一个字符串,然后将其解释为一行,则必须对此进行测试:
def myfunc(x):
if isinstance(x, basestring):
# Interpret argument as one line
x = [x]
for line in x:
doSomething(line)
或者,您可以在换行符上拆分字符串:
def myfunc(x):
if hasattr(x, 'splitlines'):
# Interpret argument as multiple lines:
x = x.splitlines()
for line in x:
doSomething(line)
如果您只接受类似文件的对象,则可以指示调用者将字符串参数包装在StringIO
:
myfunc(StringIO(s))
isinstance(var, str) 检查 var 是否为 str 类型。
我不记得手头文件的类型,但您可以通过文件 var 找出答案。它将显示在 < ... >
你可以使用:
def myfunc(x):
for line in x:
if isinstance(line, str):
print line
else:
# Its a file so do file things
一种方法是使用类似 isinstance 的方法来确定 x 是否为字符串。如果是,您可以将其传递给 StringIO(或 cStringIO)以使其成为像对象一样的文件,然后按照您的意愿进行操作。我没有对此进行测试,但它看起来大致如下:
def myfunc(x):
if isinstance(x, str):
x = StringIO.StringIO(x)
for line in x:
doSomething(line)