2017-12-03 4 views
3

제네릭 클래스에 대해 많이 읽었으며 멋진 코드이지만 때로는 제네릭 함수 만 있으면됩니다. 여기에 제가 작성한 작은 글이 있습니다 :Python의 제네릭 함수 모범 사례

def _matrix_map(self, mapper): 
    """returns the matrix applying the mapper funcfunc""" 
    return {key: mapper(value) for key, value in self._matrix.items()} 

유형에 주석을 달아야하는 이유는 무엇입니까?

T = TypeVar('T') 
def _matrix_map(self, mapper: Callable[[Tile], T]) -> Dict[Coordinate, T]: 

을 나는 그것이 mypy로 통과있어 : 일반적인 지원하는 정적으로 입력 된 언어로, 난 내가 이런 식으로 쓰기 줄 알았는데, 그래서이

private Dictionary<KeyType, ValueType> matrix; 
private Dictionary<KeyType, T> matrix_map<T>(Func<ValueType, T>) 

같은 것을 써서 이렇게, 그러나 pylint는 이것을 싫어한다. 첫 번째 줄에

:

C0103:Invalid class attribute name "T" 

그리고 두 번째 줄에

:

E0602:Undefined variable 'T' 

그래서 내가 뭔가 잘못하고 있어요 같은 느낌, 내가 변수 이름 (ttt을 변경할 수 있을까? typ?)하지만 두 번째 문제는 해결되지 않습니다. 내가 (정적 형식의) 제네릭 함수를 원하는 사람이 될 수는 없지만 어디서나 좋은 리소스를 찾을 수는 없습니다. 어떤 추천?

+0

참조? –

+0

@SamCraig 예, 그랬습니다. 문제는 유형을 찾을 수 없다는 것이 아니라 이전 줄에서 선언 한 변수 T를 찾을 수 없다는 것입니다. – McKay

답변

1

대략적으로 이렇게 보인 코드를 작성한 것 같습니다.

class Matrix: 
    T = TypeVar('T') 

    def _matrix_map(self, mapper: Callable[[Tile], T]) -> Dict[Coordinate, T]: 
     # ...snip... 

런타임에이와 실제로 mypy에/아무 문제에는 문제가 없습니다, 그러나 pylint 당신이 클래스 정의의 범위 내에서 그 "T"를 넣어 행복하지 보인다. 당신이 pylint를 충족하기 위해 할 수있는 대신이 작업을 수행하는 것입니다

T = TypeVar('T') 

class Matrix: 
    def _matrix_map(self, mapper: Callable[[Tile], T]) -> Dict[Coordinate, T]: 
     # ...snip... 

이 이전 코드와 정확히 동일합니다, 또한 pylint를 만족시킬 것입니다.

(나는 사실 pylint가 이전 버전에 만족하지 않는다는 사실은 사실 버그라고 말하고 싶습니다. 공평하게 말하자면, 타입 힌트에 대한 베스트 프랙티스에 대한 어떤 스타일 가이드도 실제로 존재하지 않습니다. 아직/중첩 범위 안에 typevar를 두는 것은 다소 드문 유스 케이스이므로,이 경우를 설명하지 않은 것으로 비난 할 수는 없습니다.)

유일한 단점은 외부에 해당 TypeVar을 갖는 것입니다 막연하게 깔끔하게 보입니다/마치 글로벌 네임 스페이스를 오염시키는 것처럼 보입니다. 예를 들어 _T과 같은 것으로 이름을 변경하여 부분적으로 완화 할 수 있습니다. 또 다른 일반 클래스 또는 함수가 필요할 때마다이 유형 변수를 재사용 할 수 있습니다. 그러면 네임 스페이스 오염을 줄이는 데 도움이 될 것입니다. 파이썬 타입 힌트와 함께 제네릭을 사용하는 방법에 대한 자세한 내용은

, 당신이 바로 타이 퍼 수입 http://mypy.readthedocs.io/en/stable/generics.html