[PYTHON] 메소드의 반환 유형이 파이썬에서 클래스 자체와 동일한 지 어떻게 지정합니까?
PYTHON메소드의 반환 유형이 파이썬에서 클래스 자체와 동일한 지 어떻게 지정합니까?
파이썬 3 다음 코드가 있습니다.
class Position:
def __init__(self, x: int, y: int):
self.x = x
self.y = y
def __add__(self, other: Position) -> Position:
return Position(self.x + other.x, self.y + other.y)
그러나 편집자 (PyCharm)는 참조 위치를 확인할 수 없다고 말합니다 (_add__ 메소드에서). 반환 유형이 Position 유형이어야한다고 어떻게 지정해야합니까?
편집 : 나는 이것이 실제로 PyCharm 문제라고 생각한다. 실제로 경고의 정보와 코드 완성을 사용합니다.
그러나 내가 틀렸다면 나를 수정하고 다른 구문을 사용해야합니다.
해결법
-
==============================
1.TL : DR : Python 3.7 이상을 사용하는 경우 주석 모듈을 가져 오면 원하는대로 작동합니다. Python 3.6 이하에서는 문자열을 사용합니다.
TL : DR : Python 3.7 이상을 사용하는 경우 주석 모듈을 가져 오면 원하는대로 작동합니다. Python 3.6 이하에서는 문자열을 사용합니다.
나는이 예외가 있다고 생각한다.
NameError: name 'Position' is not defined
이는 Python 4를 사용하지 않는 한 주석을 사용하기 전에 Position을 정의해야하기 때문입니다.
Python 3.7에는 PEP 563이 도입되었습니다. 주석 평가가 연기되었습니다. __future__ import annotations의 future 문을 사용하는 모듈은 주석을 문자열로 자동 저장합니다.
from __future__ import annotations class Position: def __add__(self, other: Position) -> Position: ...
이것은 Python 4.0에서 기본값이 될 예정입니다. 파이썬은 여전히 동적 타입 언어이기 때문에 런타임에 타입 검사가 수행되지 않으므로 주석을 입력해도 성능에 영향을주지 않아야합니다. 잘못된! 파이썬 3.7 이전에는 타이핑 모듈이 코어에서 가장 느린 파이썬 모듈 중 하나 였기 때문에 타이핑을 가져 오면 3.7으로 업그레이드 할 때 성능이 최대 7 배 향상됩니다.
PEP 484에 따르면 클래스 자체 대신 문자열을 사용해야합니다.
class Position: ... def __add__(self, other: 'Position') -> 'Position': ...
Django 프레임 워크를 사용한다면 Django 모델은 앞으로 참조를위한 문자열 (외국 모델이 자체이거나 아직 선언되지 않은 외래 키 정의)을 사용하기 때문에 익숙 할 것입니다. 이것은 Pycharm 및 다른 도구와 함께 작동해야합니다.
PEP 484 및 PEP 563의 관련 부분을 통해 여행을 보충하십시오.
class Tree: def __init__(self, left: Tree, right: Tree): self.left = left self.right = right
class Tree: def __init__(self, left: 'Tree', right: 'Tree'): self.left = left self.right = right
및 PEP 563 :
from __future__ import annotations
클래스 정의를하기 전에 더미 정의를 배치하십시오.
class Position(object): pass class Position(object): ...
이것은 NameError를 없애고 심지어 보일 수도 있습니다 :
>>> Position.__add__.__annotations__ {'other': __main__.Position, 'return': __main__.Position}
그러나 그것은 무엇입니까?
>>> for k, v in Position.__add__.__annotations__.items(): ... print(k, 'is Position:', v is Position) return is Position: False other is Position: False
파이썬 메타 프로그래밍 매직을 시도하고 데코레이터 쓰기를 원할 수 있습니다. 특수 효과를 추가하려면 클래스 정의를 원숭이 패치하십시오.
class Position: ... def __add__(self, other): return self.__class__(self.x + other.x, self.y + other.y)
데코레이터는 이와 동등한 책임을 져야합니다.
Position.__add__.__annotations__['return'] = Position Position.__add__.__annotations__['other'] = Position
적어도 그것은 옳은 것처럼 보인다.
>>> for k, v in Position.__add__.__annotations__.items(): ... print(k, 'is Position:', v is Position) return is Position: True other is Position: True
아마 너무 많은 문제.
3.6 이하를 사용하는 경우 3.7에서 __future__ import annotations에서 사용하는 클래스 이름을 포함하는 문자열 리터럴을 사용하면 올바르게 작동합니다.
-
==============================
2.'위치'라는 이름은 클래스 본문 자체가 파싱 될 때 사용할 수 없습니다. 나는 타입 선언을 어떻게 사용하는지 모르지만, Python의 PEP 484는 타이핑 힌트를 사용하는 경우 대부분의 모드에서 사용해야하는 것으로,이 시점에서 이름을 단순히 문자열로 지정할 수 있다고합니다.
'위치'라는 이름은 클래스 본문 자체가 파싱 될 때 사용할 수 없습니다. 나는 타입 선언을 어떻게 사용하는지 모르지만, Python의 PEP 484는 타이핑 힌트를 사용하는 경우 대부분의 모드에서 사용해야하는 것으로,이 시점에서 이름을 단순히 문자열로 지정할 수 있다고합니다.
def __add__(self, other: 'Position') -> 'Position': return Position(self.x + other.x, self.y + other.y)
https://www.python.org/dev/peps/pep-0484/#forward-references - 거기에있는 클래스 이름의 패키지를 풀어서 사용하도록하는 도구를 확인하십시오 (항상 사용하는 것이 중요합니다. Python 언어 그 자체는 이러한 주석의 일을하지 않는다는 것을 명심하십시오. 보통 정적 코드 분석을위한 것이거나 런타임에 유형 검사를위한 라이브러리 / 프레임 워크를 가질 수 있습니다.하지만 명시 적으로 설정해야합니다.
-
==============================
3.문자열로 타입을 지정하는 것은 괜찮지 만, 우리가 기본적으로 파서를 우회하고 있다는 것을 나에게 조금은 욕되게한다. 따라서이 리터럴 문자열 중 하나를 잘못 입력하지 않는 것이 좋습니다.
문자열로 타입을 지정하는 것은 괜찮지 만, 우리가 기본적으로 파서를 우회하고 있다는 것을 나에게 조금은 욕되게한다. 따라서이 리터럴 문자열 중 하나를 잘못 입력하지 않는 것이 좋습니다.
def __add__(self, other: 'Position') -> 'Position': return Position(self.x + other.x, self.y + other.y)
약간의 차이점은 바운드 된 typevar를 사용하는 것입니다. 적어도 다음과 같이 typevar를 선언 할 때 문자열을 한 번만 써야합니다.
from typing import TypeVar T = TypeVar('T', bound='Position') class Position: def __init__(self, x: int, y: int): self.x = x self.y = y def __add__(self, other: T) -> T: return Position(self.x + other.x, self.y + other.y)
from https://stackoverflow.com/questions/33533148/how-do-i-specify-that-the-return-type-of-a-method-is-the-same-as-the-class-itsel by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 파이썬에서 matplotlib로 대수 축 플롯 (0) | 2018.10.02 |
---|---|
[PYTHON] Matplotlib은 틱 레이블 글꼴 크기를 더 작게 만듭니다. (0) | 2018.10.02 |
[PYTHON] Python 3.6의 변수 주석은 무엇입니까? (0) | 2018.10.02 |
[PYTHON] Python Pandas 집계 결과에서 과학 표기법 형식 지정 / 표시 안 함 (0) | 2018.10.02 |
[PYTHON] 두 날짜를 비교하는 방법? (0) | 2018.10.02 |