回答:
実行しているPEP-8の推奨事項は次のとおりです。
ラムダ式を名前に直接バインドする割り当てステートメントではなく、常にdefステートメントを使用します。
はい:
def f(x): return 2*x
番号:
f = lambda x: 2*x
最初の形式は、結果の関数オブジェクトの名前が総称 '<lambda>'ではなく、具体的には 'f'であることを意味します。これは、トレースバックや文字列表現に一般的に役立ちます。割り当てステートメントを使用すると、ラムダ式が明示的なdefステートメントよりも提供できる唯一の利点がなくなります(つまり、より大きな式の中に埋め込むことができます)。
ラムダを名前に割り当てると、基本的にはの機能が複製さdef
れます。一般的に、混乱を避けて明確にするために、単一の方法で何かを行うのが最善です。
ラムダの正当な使用例は、関数を割り当てずに使用したい場合です。例:
sorted(players, key=lambda player: player.rank)
一般に、これを行うことに対する主な議論は、def
ステートメントによってコードの行数が増えることです。それに対する私の主な反応は次のとおりです。はい、それで結構です。あなたがコードゴルフをしているのでない限り、行数を最小限に抑えることはあなたがすべきことではありません。
def
。PEP8チェッカーを使用して推奨されるアプローチを実行すると、が得られE704 multiple statements on one line (def)
、2行に分割すると、次のようになりますE301 expected 1 blank line, found 0
:-/
ここに話があります、私は私が2回使用していた単純なラムダ関数を持っていました。
a = map(lambda x : x + offset, simple_list)
b = map(lambda x : x + offset, another_simple_list)
これは表現のためだけのものであり、私はこれのいくつかの異なるバージョンに直面しています。
今、物事をドライに保つために、私はこの一般的なラムダを再利用し始めます。
f = lambda x : x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
この時点で、コード品質チェッカーはラムダが名前付き関数であると文句を言うので、関数に変換します。
def f(x):
return x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
これで、チェッカーは、関数の前後に1行の空白行が必要であると不平を言います。
def f(x):
return x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
ここでは、元の2行ではなく6行のコードがあり、可読性の向上やPythonicの増加はありません。この時点で、コードチェッカーはdocstringを持たない関数について文句を言います。
私の意見では、このルールは、それが理にかなっている場合は避けて違反する方がよいと思います。
a = [x + offset for x in simple_list]
。使用する必要はありませんmap
し、lambda
ここに。
x + offset
、コードの複数行を変更せずに更新できる抽象化された場所に部分を移動することであったと思います。あなたが述べたようにリスト内包表記を使用しても、x + offset
それらを含むコードの2行がまだリスト内包表記に含まれている必要があります。著者が望むとおりにそれらを引き出すためには、def
またはが必要lambda
です。
def
してlambda
1も使用することができfunctools.partial:f = partial(operator.add, offset)
当時とa = list(map(f, simple_list))
。
def f(x): return x + offset
(つまり、単一の行で定義された単純な関数)?少なくともflake8を使用すると、空白行に関する不満はありません。
a, b = [[x + offset for x lst] for lst in (simple_list, another_simple_list)]
Lattywareは完全に正しい:基本的にPEP-8は次のようなことを避けて欲しい
f = lambda x: 2 * x
代わりに使用
def f(x):
return 2 * x
ただし、最近のバグレポート(2014年8月)で対処されているように、次のようなステートメントが準拠しています。
a.f = lambda x: 2 * x
a["f"] = lambda x: 2 * x
私のPEP-8チェッカーはまだこれを正しく実装していないため、当面はE731をオフにしました。
def
、PEP8チェッカーはと文句を言うE301 expected 1 blank line, found 0
ため、その前に醜い空白行を追加する必要があります。
また、def(ined)関数を使用することさえ不可能である状況に遭遇しました。
class SomeClass(object):
# pep-8 does not allow this
f = lambda x: x + 1 # NOQA
def not_reachable(self, x):
return x + 1
@staticmethod
def also_not_reachable(x):
return x + 1
@classmethod
def also_not_reachable(cls, x):
return x + 1
some_mapping = {
'object1': {'name': "Object 1", 'func': f},
'object2': {'name': "Object 2", 'func': some_other_func},
}
この場合、本当にクラスに属するマッピングを作成したかったのです。マッピング内の一部のオブジェクトには同じ機能が必要でした。名前付き関数をクラスの外に置くのは非論理的でしょう。クラス本体の内部からメソッド(staticmethod、classmethod、またはnormal)を参照する方法が見つかりませんでした。コードが実行されたとき、SomeClassはまだ存在していません。したがって、クラスから参照することもできません。
also_not_reachable
にマッピング定義で参照できますSomeClass.also_not_reachable
f
2.7と3.5の両方と同じくらい到達可能です
@staticmethod
と含まれて@classmethod
いないオブジェクトSomeClass.also_not_reachable
(区別できる名前が必要です)。クラスメソッドからそれらにアクセスする必要がある場合は、次を使用してくださいself.also_not_reachable
*not_reachable
メソッドの名前をnot_as_easily_reachable_from_class_definition_as_a_lambda
xDに変えるべきです
flake8
(flake8.pycqa.org)に言及しています