파이썬 함수 정의에서->은 무엇을 의미합니까?


476

최근에 Python 3.3 문법 사양을 볼 때 흥미로운 것을 발견했습니다 .

funcdef: 'def' NAME parameters ['->' test] ':' suite

선택적 'arrow'블록은 Python 2에 없었으며 Python 3에서 그 의미에 관한 정보를 찾을 수 없었습니다. 이것은 올바른 Python이며 해석기가 허용합니다.

def f(x) -> 123:
    return x

나는 이것이 일종의 전제 조건 구문 일 수 있다고 생각했지만,

  • x아직 정의되지 않았으므로 여기서 테스트 할 수 없습니다 .
  • 화살표 (예 :) 뒤에 무엇을 놓든 2 < 1기능 동작에는 영향을 미치지 않습니다.

이 구문에 익숙한 사람이 설명 할 수 있습니까?

답변:


375

그것은의 기능 주석 .

좀 더 자세하게, 파이썬 2.x에는 docstring이있어 메타 데이터 문자열을 다양한 유형의 객체에 첨부 할 수 있습니다. 이것은 놀랍도록 편리하므로 Python 3은 메타 데이터를 매개 변수 및 반환 값을 설명하는 함수에 첨부 할 수 있도록하여 기능을 확장합니다.

선험적 인 유스 케이스는 없지만 PEP는 몇 가지를 제안합니다. 매우 편리한 방법 중 하나는 예상되는 유형으로 매개 변수에 주석을 달 수 있다는 것입니다. 그러면 주석을 확인하거나 인수를 올바른 유형으로 강제하는 데코레이터를 작성하는 것이 쉬울 것입니다. 다른 하나는 docstring으로 인코딩하는 대신 매개 변수 별 문서를 허용하는 것입니다.


122
정보는 .__annotations__속성으로 제공됩니다 .
Martijn Pieters

8
와우, 반환 값 주석뿐만 아니라 매개 변수 주석과 같은 광범위한 지식이 누락되었습니다. 대단히 감사합니다 :).
Krotton

4
@Krotton 그것을 놓친 것에 대해 당신을 비난 할 수는 없습니다. 그것은 실제로 사용되지 않습니다. 나는 그것들을 사용하여 하나의 라이브러리 만 만났으며 꽤 모호합니다.

5
그리고 __annotations__속성은 사전입니다. 키 return는 화살표 뒤의 값을 검색하는 데 사용되는 키 입니다.
Keith

9
@delnan-아마도 대부분 사용되지 않는 이유는 대부분의 파이썬 라이브러리가 여전히 python2.x와 호환되는 것을 목표로하기 때문입니다. python3.x가보다 표준화되기 시작하면서, 우리는 이런 것들이 더 많이
여기저기서 나타나는

252

이것들은 PEP 3107 에서 다루는 함수 주석 입니다. 특히, ->리턴 함수 주석을 표시합니다.

예 :

>>> def kinetic_energy(m:'in KG', v:'in M/S')->'Joules': 
...    return 1/2*m*v**2
... 
>>> kinetic_energy.__annotations__
{'return': 'Joules', 'v': 'in M/S', 'm': 'in KG'}

주석은 사전이므로 다음과 같이 할 수 있습니다.

>>> '{:,} {}'.format(kinetic_energy(20,3000),
      kinetic_energy.__annotations__['return'])
'90,000,000.0 Joules'

문자열이 아닌 파이썬 데이터 구조를 가질 수도 있습니다.

>>> rd={'type':float,'units':'Joules','docstring':'Given mass and velocity returns kinetic energy in Joules'}
>>> def f()->rd:
...    pass
>>> f.__annotations__['return']['type']
<class 'float'>
>>> f.__annotations__['return']['units']
'Joules'
>>> f.__annotations__['return']['docstring']
'Given mass and velocity returns kinetic energy in Joules'

또는 함수 속성을 사용하여 호출 된 값의 유효성을 검사 할 수 있습니다.

def validate(func, locals):
    for var, test in func.__annotations__.items():
        value = locals[var]
        try: 
            pr=test.__name__+': '+test.__docstring__
        except AttributeError:
            pr=test.__name__   
        msg = '{}=={}; Test: {}'.format(var, value, pr)
        assert test(value), msg

def between(lo, hi):
    def _between(x):
            return lo <= x <= hi
    _between.__docstring__='must be between {} and {}'.format(lo,hi)       
    return _between

def f(x: between(3,10), y:lambda _y: isinstance(_y,int)):
    validate(f, locals())
    print(x,y)

인쇄물

>>> f(2,2) 
AssertionError: x==2; Test: _between: must be between 3 and 10
>>> f(3,2.1)
AssertionError: y==2.1; Test: <lambda>

86

다른 답변에서 언급했듯이 ->기호는 함수 주석의 일부로 사용됩니다. 그러나 최신 버전의 Python >= 3.5에서는 정의 된 의미를 갖습니다.

PEP 3107-기능 주석은 문법 변경, func.__annotations__그것들 의 존재 여부 및 사용 사례가 아직 열려 있다는 사실을 정의하여 사양을 설명했다 .

파이썬 3.5에서 PEP 484-타입 힌트 는 이것에 하나의 의미를 부여합니다 : ->함수가 반환하는 타입을 나타내는 데 사용됩니다. 또한 주석의 기존 사용은 어떻습니까?에 설명 된대로 향후 버전에서도 적용되는 것 같습니다.

가장 빠른 방법은 3.6에서 비 유형 힌트 주석을 자동으로 더 이상 사용하지 않고 3.7에서 전체 비추천을 사용하고 Python 3.8에서 주석을 사용할 수있는 유일한 유형으로 유형 힌트를 선언합니다.

(엠파 시스 마인)

3.6내가 실제로 알 수있는 한 실제로 구현되지 않았 으므로 향후 버전에 충돌 할 수 있습니다.

이에 따르면, 제공 한 예는 다음과 같습니다.

def f(x) -> 123:
    return x

향후에는 금지되며 (현재 버전에서는 혼동 될 수 있음) 다음과 같이 변경해야합니다.

def f(x) -> int:
    return x

함수 f가 타입의 객체를 반환 한다는 것을 효과적으로 설명하기 위해서 int.

주석은 파이썬 자체에서 어떤 식 으로든 사용되지 않으며 거의 ​​채워지고 무시합니다. 그들과 함께 작업하는 것은 최대 타사 라이브러리입니다.


64

다음 코드에서

def f(x) -> int:
    return int(x)

-> int단지 그 이야기 f()의 정수를 반환합니다 (그러나 그것은 정수를 반환하는 기능을 강요하지 않습니다). 이를 반환 주석 이라고하며 액세스 할 수 있습니다 f.__annotations__['return'].

파이썬은 또한 매개 변수 주석을 지원합니다 :

def f(x: float) -> int:
    return int(x)

: float프로그램 (및 일부 타사 라이브러리 / 프로그램, 예를 들어 pylint) 읽는 사람 알려줍니다 x되어야한다 float. 로 액세스 f.__annotations__['x']되며 그 자체로는 의미가 없습니다. 자세한 내용은 설명서를 참조하십시오.

https://docs.python.org/3/reference/compound_stmts.html#function-definitions https://www.python.org/dev/peps/pep-3107/


4

이것은 함수가 반환하는 결과의 유형을 의미하지만 None.

Python 3.x를 지향하는 최신 라이브러리에 널리 퍼져 있습니다.

예를 들어, 라이브러리 팬더 프로파일 링 코드에는 여러 장소가 있습니다.

def get_description(self) -> dict:

def get_rejected_variables(self, threshold: float = 0.9) -> list:

def to_file(self, output_file: Path or str, silent: bool = True) -> None:
"""Write the report to a file.

"이는 함수가 반환하는 결과 유형을 의미하지만 None 일 수 있습니다." None 또는 다른 유형일 수 있습니다.
Ebram Shehata

2

def function(arg)->123:

단순히 반환 유형이며, 이 경우 정수 는 어떤 숫자를 쓰든 중요하지 않습니다.

자바 처럼 :

public int function(int args){...}

그러나 파이썬 ( Jim Fasarakis Hilliard가 말한 방법) 의 반환 유형은 힌트 일뿐 이므로 반환을 제안하지만 어쨌든 문자열과 같은 다른 유형을 반환 할 수 있습니다.


1
def f(x) -> 123:
    return x

내 요약 :

  1. ->개발자가 함수의 반환 유형을 선택적으로 지정할 수 있도록 간단히 소개되었습니다. Python Enhancement Proposal 3107 참조

  2. 이것은 파이썬이 광범위하게 채택됨에 따라 미래에 어떻게 발전 할 수 있는지를 나타냅니다. 강한 타이핑에 대한 표시입니다. 이것은 개인적인 관찰입니다.

  3. 인수의 유형도 지정할 수 있습니다. 함수 및 인수의 반환 유형을 지정하면 논리적 오류를 줄이고 코드 향상을 향상시키는 데 도움이됩니다.

  4. 함수는 함수 및 매개 변수 수준에서 모두 반환 형식으로 식을 사용할 수 있으며 식의 결과는 주석 개체의 'return'특성을 통해 액세스 할 수 있습니다 . 람다 인라인 함수의 표현식 / 반환 값에 대해서는 주석 이 비어 있습니다.


수정 해 주셔서 감사합니다.
마즈
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.