入力引数の行を反復処理する Python 関数を書きたいのですが、文字列またはファイルのようなオブジェクトを受け入れることができます。これを行う方法はありますか?
def myfunc(x):
for line in x:
doSomething(line)
上記のコードは、ファイルのようなオブジェクトでは機能しますが、文字列では機能しません。実際のタスクは上記よりもはるかに複雑であるため、関数を 2 つではなく 1 つだけ記述したいと思います。
入力引数の行を反復処理する Python 関数を書きたいのですが、文字列またはファイルのようなオブジェクトを受け入れることができます。これを行う方法はありますか?
def myfunc(x):
for line in x:
doSomething(line)
上記のコードは、ファイルのようなオブジェクトでは機能しますが、文字列では機能しません。実際のタスクは上記よりもはるかに複雑であるため、関数を 2 つではなく 1 つだけ記述したいと思います。
ダックタイピングを使用します。
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)
ここで使用できる約100万のバリアントがあります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)
ファイルのようなオブジェクトを受け入れるだけの場合は、呼び出し元に文字列引数を でラップするように指示できますStringIO
。
myfunc(StringIO(s))
文字列に対しても機能しますが、文字列を 1 文字ずつ反復処理します。ユーザーは、代わりに文字列のリストを使用して関数を呼び出す必要があります。
1 つの文字列を渡すことを明示的にサポートしたい場合は、それが行として解釈されるようにするには、それをテストする必要があります。
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)
1つのアプローチは、isinstanceのようなものを使用して、xが文字列であるかどうかを判別することです。もしそうなら、それをStringIO(またはcStringIO)に渡して、オブジェクトのようなファイルにしてから、必要に応じて続行することができます。私はこれをテストしていませんが、大まかに次のようになります。
def myfunc(x):
if isinstance(x, str):
x = StringIO.StringIO(x)
for line in x:
doSomething(line)
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