E731 람다 식을 할당하지 않고 def를 사용하십시오. pep8 경고가 나타납니다. 람다

람다 식을 사용할 때 마다이 pep8 경고가 나타납니다. 람다 식은 권장되지 않습니까? 왜 그렇지 않습니까?



답변

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명령문이 더 많은 코드 행을 생성 한다는 것입니다. 그것에 대한 나의 주요 반응은 다음과 같습니다. 그렇습니다. 코드 골프를하지 않는 한 줄 수를 최소화하는 것은해야 할 일이 아닙니다.


답변

여기에 이야기가 있습니다. 두 번 사용했던 간단한 람다 함수가 있습니다.

a = map(lambda x : x + offset, simple_list)
b = map(lambda x : x + offset, another_simple_list)

이것은 단지 표현을위한 것이며, 나는 이것의 다른 버전에 직면했습니다.

이제 DRY를 유지하기 위해이 일반적인 람다를 재사용하기 시작합니다.

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)

이제 검사기는 함수가 앞뒤로 하나의 빈 줄로 묶여 있어야한다고 불평합니다.

def f(x):
    return x + offset

a = map(f, simple_list)
b = map(f, another_simple_list)

여기 우리는 가독성을 높이 지 않고 파이 토닉을 증가시키지 않고 원래 2 줄 대신 6 줄의 코드를 가지고 있습니다. 이 시점에서 코드 검사기는 docstring이없는 함수에 대해 불평합니다.

제 생각에는이 규칙을 피하고 깨뜨리는 것이 좋습니다. 판단력을 사용하십시오.


답변

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 (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},
  }

이 경우 클래스에 속한 매핑을 만들고 싶었습니다. 매핑의 일부 객체에는 동일한 기능이 필요했습니다. 명명 된 함수를 클래스 외부에 두는 것은 비논리적입니다. 클래스 본문 내부에서 메서드 (정적 메서드, 클래스 메서드 또는 일반)를 참조하는 방법을 찾지 못했습니다. 코드가 실행될 때 SomeClass가 아직 존재하지 않습니다. 따라서 수업에서 그것을 언급하는 것도 불가능합니다.