ラムダ式を使用すると、このpep8警告が表示されます。ラムダ式は推奨されませんか?そうでない場合はなぜですか?
PEP-8 での推奨事項は次のとおりです。
ラムダ式を名前に直接バインドする割り当てステートメントの代わりに、常にdefステートメントを使用します。
はい:
def f(x): return 2*x
いいえ:
f = lambda x: 2*x
最初の形式は、結果の関数オブジェクトの名前が、一般的な「<lambda>」ではなく具体的に「f」であることを意味します。これは、一般的なトレースバックや文字列表現に役立ちます。割り当てステートメントを使用すると、ラムダ式が明示的なdefステートメントに対して提供できる唯一の利点がなくなります(つまり、大きな式の中に埋め込むことができます)
ラムダを名前に割り当てることは、基本的にdef
の機能を複製するだけです。一般に、混乱を避けて明快さを高めるために何かを行うのが最善です。
Lambdaの正当な使用例は、関数を割り当てずに使用したい場合です。例えば:
sorted(players, key=lambda player: player.rank)
単純な操作の場合、 operator
モジュール は attrgetter
、 itemgetter
およびlabmdasを頻繁に置き換えることができる methodcaller
の便利なオプションを提供します属性、アイテム、メソッドの呼び出しにアクセスしているだけです。
たとえば、上記はoperator.attrgetter
で次のように実行できます。
sorted(players, key=operator.attrgetter('rank'))
ここに物語があります、私は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を持たない関数について文句を言います。
私の意見では、このルールは理にかなっている場合は避けるべきであり、それを破る方が賢明です。
また、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はまだ存在していません。したがって、クラスからそれを参照することもできません。