1

コメント行を消去したいファイルがあります。次のような方法で、操作に使用したいと思います。functools.partial

from functools import partial

f = open(filetoread, "r")
lines = f.readlines()
f.close()

# Filtering the comment lines
f_func = partial(str.startswith, prefix="#")
lines = filter(f_func, lines)

str.startswithどうやらクラスメソッドであるため、これは機能しません。functools.partialそれが機能するように使用する適切な方法は何str.startswithですか?

4

2 に答える 2

6

次の 3 つの問題があります。

まず、str.startswithキーワード引数を取らず、位置引数のみを取ります。これは C で実装されておりPyArg_ParseTuple、位置引数を取得するために使用します。prefix名前は docstring にのみ表示されるため、Python に名前を伝えるものは何もありません。それでprefix=ダメです。この問題は次のようなものです。

>>> str.startswith('#hi', prefix='#')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: startswith() takes no keyword arguments
>>> def foo(self,prefix,start=None,end=None): return str.startswith(self,prefix,start,end)
...
>>> foo('#hi', prefix='#')
True

次に、 の最初の引数は接頭辞でstr.startswithはなく、接頭辞がselfあるかどうかをチェックするオブジェクトです。メソッドであること自体に問題はありませんstr.isprefixof。しかし、そうではありません。

最後に、functools.partial最初の位置引数のみをバインドできます。2 番目をバインドする方法はわかりませんが、最初の引数はバインドできません。バインドしたい引数は最初のものではなく、名前でアクセスできないため、選択肢がありません。

ただし、この場合の回避策として、機能的なスタイルのコードを作成する方法があります。あなただけが必要operator.methodcallerですfunctools.partial:

f_func = operator.methodcaller('startswith', '#')

operator.methodcaller最初の引数を除くすべての引数をバインドします。


を使用する適切な方法を尋ねるのでfunctools、引数を逆にする追加の高階関数を使用してそれを行うことができると思います。

def flip(func):
    return lambda x,y: func(y,x)

f_func = partial(flip(str.startswith), '#')

ラムダを使用するため、これは「不正行為」と見なすことができます。ラムダを使用したい場合は、ダニエルの回答のように使用します。しかし、Python が提供しない基本的な高階関数を実装するためにそれを使用しています。それが邪魔にならないようにすれば、定義する行f_funcは素晴らしく機能的に感じられます。

注意していただきたいのは、Python の用語で言えば、ここではその高階関数を特にうまくpartial実装していないということです。funcユーザーが合理的に提供したい読み取り専用属性もありますflip

str.startswithあるいは、上記のように Python ラッパーを に書き、fooそれに適用partialすることもできます。

于 2015-02-24T12:11:01.763 に答える
1

ここでは、パーシャルが適切なツールではないと思います。代わりに、ラムダを使用できます。

func = lambda s: s.startswith('#')
lines = filter(func, lines)

ただし、Python は実際には関数型言語ではないことに注意してください。これを行うより Python 的な方法は、リスト内包表記を使用することです。

lines = [line for line in lines if line.startswith('#')]
于 2015-02-24T11:59:08.747 に答える