답변:
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)
있고 두 줄로 E301 expected 1 blank line, found 0
여기에 이야기가 있습니다. 두 번 사용했던 간단한 람다 함수가 있습니다.
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이없는 함수에 대해 불평합니다.
제 생각에는이 규칙을 피하고 깨뜨리는 것이 좋습니다. 판단력을 사용하십시오.
a = [x + offset for x in simple_list]
. 필요 없음 사용에 map
와 lambda
여기.
x + offset
한 줄 이상의 코드를 변경하지 않고 업데이트 할 수있는 추상적 인 위치로 부분 을 옮기는 것이 요점이라고 생각합니다 . 언급 한대로 목록 이해를 사용하면 x + offset
방금 목록 이해에 포함 된 두 줄의 코드가 여전히 필요합니다 . 저자가 원하는대로 사람들을 끌어하기 위해, 당신은 필요 def
이상 lambda
.
def
하고 lambda
하나는 사용할 수 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},
}
이 경우 클래스에 속한 매핑을 만들고 싶었습니다. 매핑의 일부 객체에는 동일한 기능이 필요했습니다. 명명 된 함수를 클래스 외부에 두는 것은 비논리적입니다. 클래스 본문 내부에서 메서드 (정적 메서드, 클래스 메서드 또는 일반)를 참조하는 방법을 찾지 못했습니다. 코드가 실행될 때 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
flake8
( flake8.pycqa.org )