파이썬 함수 호출에서 사용되지 않는 반환 매개 변수에 사용할 스타일


30

함수가 값의 튜플을 반환하지만 나중에 그 값 중 하나만 사용되는 상황을 처리하기 위해 권장 / 일반적으로 허용되는 코딩 스타일이 있습니까? 전화는 아마도 약간 과잉 일 것입니다…)? 대신에

a, b, c = foo()

다음 그냥 사용하지 않는 bc다음과 같은 변종의 바람직한해야하는 (또는 다른가?)

변형 1 (밑줄)

a, _, _ = foo()

(매우 명확하고 단순하지만 _ = gettext.gettext번역을 사용하는 많은 응용 프로그램에서 충돌이 발생할 수 있습니다 )

변형 2 (더미 이름)

a, unused, unused = foo()

(매우 호소하지는 않지만 같은 다른 이름도 마찬가지입니다 dummy)

변형 3 (인덱스)

a = foo()[0]

(나에게 ()[0]비 -pythonic 외모…)


이전 답변과 달리, 이제 반환 값의 2/3를 참조하려고 할 때 변형 3에서는 어떻게됩니까? 파이썬을 정당화하기에 충분하지 않다는 것을 깨달았 기 때문에 대답을 제거했습니다.
Craige

@Craige : 당신은 당신이 여부를 묻는 ... 그것을 제거하기 전에 내가 대답을 보지 않았다 a, b = foo()[0:2]일 것이다? 그렇다면 : 그렇습니다. :)
user49643

그것이 바로 내가 요구 한 것입니다. 그것이 작동하면 (당신이 말했듯이) 변형 3을 사용할 것입니다.이 정보가 주어지면 내 대답을 회복하고 있습니다.
Craige

3
그런데, 요즘은 당신을 위해 오히려 아름다운 구문을 사용할 수 있습니다 풀고 '확장'을 : a, *_ = foo()첫 번째 제외한 모든 값을 버려야합니다.
Benjamin Hodgson

답변:


17

사용되지 않은 변수에 밑줄을 사용하는 것은 확실합니다. 그러나 일부 코드베이스에서는 식별자가의 약어로 예약되어 있으므로 옵션이 아닙니다 gettext. 이것은이 스타일에 대한 가장 빈번한 이의 제기입니다 (내가 판단 할 수있는 한 대다수에게는 문제가되지는 않습니다). 나는 아직도 그것을 추천하고 항상 그것을 직접 사용합니다.

이름은 개인적으로 나를 자극 dummy하거나 unused자극하는 경향이 있으며, 나는 종종 그것을 자주 보지 못합니다 (파이썬에서는- dummy자유롭게 사용하는 델파이 코드베이스를 알고 있으며 문제의 프로그램과 관련된 스크립트로 유출되었습니다). 나는 당신에게 그것에 대해 조언합니다.

반환 된 튜플에서 하나의 항목을 추출해도됩니다. 또한 사용되지 않은 값의 수를 올바르게 얻는 번거 로움을 덜어줍니다. 그러나 두 가지 잠재적 단점이 있습니다.

  • 값의 수가 예상과 다르면 폭발하지 않습니다. 이것은 믹스 업 및 오타를 감지하는 데 유용 할 있습니다.
  • 반환 값이 시퀀스 일 때만 작동합니다 (주로 튜플 및 목록이지만 일반적으로 유지합시다). 필자는 내 코드에서 반복 가능하고 일정한 수의 값을 생성하므로 언 패킹 할당에 사용할 수 있지만 인덱싱 할 수없는 클래스 (2D 벡터)를 알고 있습니다.

나는 않았다 실제로 어쨌든, 나는 당신의 대답을 받아 :) 내 질문에와 gettext는 말할 - 명확한 하나의 허용 스타일이없는 것 같습니다 그러나 당신의 대답은 몇 가지 흥미로운 점을 올렸다.
user49643

gettext 관련 문제를 피하기 위해 (또는 인터프리터에서 유사한 문제를 피하기 위해) 단일 밑줄 대신 이중 밑줄 (일명 천둥)을 사용할 수 있습니다.

21

Pylint는 이런 식으로 습관을 냈습니다.

widget, _parent, _children = f()

즉, 사용하지 않는 결과에는 접두사가 _로 설명되는 이름이 있습니다. Pylint는 접두사가 _ 인 로컬은 사용되지 않은 것으로, 접두사가 붙은 전역 또는 속성은 _를 개인으로 간주합니다.


3

전체 프로젝트 에서이 작업을 한 번만 수행하거나 특정 기능을 거의 사용 gettext하지 않는 경우 해당 모듈에 문제가없는 경우 변형 1을 사용 하고 그렇지 않으면 변형 3을 사용합니다.

반면에, 당신이 이것을 많이하고 있다면-특히 반환 값 의 다른 하위 집합 을 원할 때 마다 (래퍼가 원하는 것을 반환하는 래퍼 만들기) 래퍼를 작성하는 것이 유리 할 수 ​​있습니다 결과를 명명 된 tuple 또는 다른 설명 클래스의 인스턴스에 넣습니다 .

bar = foo()

그런 다음 bar.a, bar.b및 로 작업하십시오 bar.c.


2

다른 사람들이 말했듯이 밑줄 ( _)이 표준입니다. 그러나 밑줄을 번역에 사용하는 경우 이중 밑줄이 가장 좋은 대안이라고 생각합니다.

var, __, value = "VAR=value".partition('=')

이것들보다 낫다 :

var, unused, value = "VAR=value".partition('=')

var, unused_del, value = "VAR=value".partition('=')

var, _del, value = "VAR=value".partition('=')


1

나는 비 파이썬 프로그래머이지만 세 번째 변형이 가장 적합합니다.

변형 3에서는 어떤 값을 다루고 싶은지 분명히 알 수 있습니다. 변형 1과 2에서는 값을 변수에 다시 할당하므로 사용할 수 있습니다. 이름을 불명확하게 지정했을 수도 있지만 이름이 잘못 지정 되어도 실제로 문제를 해결할 수있는 것은 아닙니다.

명확성을 제외하고 왜 사용하지 않는 값을 메모리의 슬롯에 할당하려고합니까 (변형 1 및 2에서와 같이)? 이것은 메모리 관리 측면에서 좋지 않은 솔루션입니다.


항상 같은 변수에 넣으면 메모리 문제가 주어진 시간에 단일 변수의 크기 일뿐입니까? 나는 그것이 문제가 될 것이라고 생각하지 않습니다.
Michael McQuade

-2

일반적인 규칙은 다음과 같습니다. 반환 된 값 중 1 개만 사용하는 경우 해당 값 1 만 반환하면 어떨까요? 여러 장소에서 플래그를 호출하는 경우 플래그를 동일하게 유지하고 플래그별로 값을 반환하십시오.

편집하다:

내가 당신의 상황에 있었고 함수를 작성하지 않았다면 아마도 변형 2를 사용했을 것입니다. 필요한 경우 매개 변수를 사용할 수 있도록 더미 이름을 유지합니다. 목록을 자르면 약간의 오버 헤드가 발생합니다. 아마도 원치 않는 데이터를 수신하기 위해 몇 바이트를 절약 할 수 있습니다.


-1 그가 함수를 정의하지 않았으므로 리턴하는 것을 변경할 수 없습니다. 함수가 3 개의 값을 반환 할 때 참조하고 있다고 생각하지만 현재 유스 케이스에서는 약 1 만 신경 쓰고 있습니다.
Craige

@Craige : 예, 변경할 수없는 기능을 의미했습니다. 내 질문에이를 명확히하는 메모를 추가했습니다.
49643

오버 헤드가 확실합니까? 나는 매우 간단한 ipython 테스트를 시도했다. %timeit a, _, _ = foo()vs. %timeit a = foo()[0]123ns 대 109ns가 발생했다. 아니면 특정한 상황을 염두에 두셨습니까?
user49643

2
또 다른 그럴듯한 시나리오는 일부 통화에 대해 모든 값이 필요하지 않다는 것 입니다.
Keith Thompson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.