• 티스토리 홈
  • 프로필사진
    Cat_Code
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
Cat_Code
  • 프로필사진
    Cat_Code
    • 분류 전체보기 (116)
      • [네이버 부스트캠프] (46)
        • ⭐주간 학습 정리 (43)
        • 🎶추가 학습 정리 (3)
      • [연습의 흔적들] (27)
        • 백준⚾ (26)
        • 캐글 & 데이콘 🤝 (1)
      • [ML] (23)
        • 머신러닝 💕 (5)
        • 딥러닝 🔫 (10)
        • 데이터 분석 🖤 (1)
        • 수학 ☑️ (4)
        • LLM🦜 (3)
      • [CS] (16)
        • 파이썬 🖤 (12)
        • 해체 분석기📝 (3)
        • Service Product (1)
        • MultiMedia (0)
      • [개발일지] (2)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • [Python] Typing 2편
        2023년 05월 31일
        • Cat_Code
        • 작성자
        • 2023.05.31.:29

        참고한 자료

         

        파이썬 Typing 파헤치기 - 심화편

        지난 글 '파이썬 Typing 파헤치기 - 기초편'에서는 Typing의 기본적인 내용과 8개의 타입에 대해 다루어봤습니다. 이번 포스트에서는 조금 더 심화된 타입들에 대해 다뤄보도록 하겠습니다. 심화 타

        sjquant.tistory.com

         

        지난 글 

         

        [Python] Typing 1편

        참고자료 파이썬 Typing 파헤치기 - 기초편 동적 언어에서의 타입 검사 파이썬은 동적 언어로 잘 알려진 언어입니다. 즉, 변수의 타입을 일일이 명시하지 않아도 되고, 특정 변수의 타입이 중간에

        eumgill98.tistory.com

        우리는 지난 시간에 Python의 Typing기능의 간단한 기초를 알아보았다

        이번 시간에는 조금더 심화 과정의 Typing을 알아볼려고 한다

         

        위에 참고한 블로그 주소가 있는데

        조금더 자세한 내용을 알고 싶다면 참고하길 바란다 !! 

         

        1. tying.Callable[..., ReturnType]

        우리는 지난 시간에 함수를 인자로 받는 경우 어떻게 typing을 해야하는지 배웠다

        tying.Callable을 사용해서 [[input Type], ReturnType]을 입력해주었다

        그러면 만약 input type을 신경쓰고 싶지 않다면 어떻게 해야할까

         

        이때 사용할 수 있는 것이 tying.Callable[..., ReturnType]이다

        쉽게 말해서 ... 을 활용해서 그냥 넘기면 된다

        def on_some_event_happened(callback: Callable[..., int]) -> None:
            ...
        
        def do_this(a: int, b: str, c:str) -> int:
            ...
        
        on_some_event_happened(do_this)

         

        2. typing.TypeVar

        Python에서 여러 타입을 일반화 하는 것을 Generic type이라고 한다

        이러한 Generic을 Typing 하는 방법은 TypeVar를 활용하면된다

        from typing import Sequence, TypeVar, Iterable
        
        T = TypeVar("T") 
        
        def batch_iter(data: Sequence[T], size: int) -> Iterable[Sequence[T]]:
            for i in range(0, len(data), size):
                yield data[i:i + size]

        해석하자면 위의 함수는 Input으로 Sequence[int] or Sequence[str] or Sequence[float] 등 다양한 형태의 type이 모두 들어갈 수 있고 이를 통해서 Iterable한 Sequence형태의 output이 만들어진다

         

        Bound

        또한 여기에 bound을 적용해서 타입의 종류를 지정해줄 수 있다

        from typing import Sequence, TypeVar, Iterable, Union
        
        T = TypeVar("T", bound=Union[int, str, bytes])
        
        
        def batch_iter(data: Sequence[T], size: int) -> Iterable[Sequence[T]]:
            for i in range(0, len(data), size):
                yield data[i:i + size]

        즉, 상속될 수 있는 타입을 지정해 줄 수 있는 것이다

         

        여기서 TypeVar['T']에서 'T'는 해당 바운드에 해당하는 모든 type을 허용한다는 것이다

        만약 'T' 대신에 들어갈 수 있는 것에는 'S'와 'A' 등의 약속과 같은 기호를 넣을 수 있다 - 반드시는 아님, 지정가능

         

        S = TypeVar('S', bound=str) ## Can be any subtype of str
        A = TypeVar('A', str, bytes)  # Must be exactly str or bytes

         

        TypeVar의 파라미터로 들어 갈 수 있는 것을 조금더 살펴보면

        class typing.TypeVar(name, *constraints, bound=None, covariant=False, contravariant=False)

        여기서 name은 'T', 'S' 등이고 constraints은 위의 A를 활용한 코드에서 str, bytes를 지정해준 것으로 반드시  해당 type이어야하는 것을 의미하고 , bound는 수용할 수 있는 타입의 집합을 지정해주는 것이다

        참고로 bound와 constraints는 동시에 될 수 없다

         

        또한  covariant, contravariant는 아래에서 한번더 나오지만  

        아래의 Stack overflow의 설명을 참고하시길..

         

        Python typing what does TypeVar(A, B, covariant=True) mean?

        Today I took a deep dive into Liskov's Substitution Principle and covariance/contravariance. And I got stuck on the difference between: T = TypeVar("T", bound=Union[A, B]) T = TypeVar("T", A, B,

        stackoverflow.com

        3. typing.Generic

        위에서 배운 TypeVar를 통해서 Generic 타입의 의존관계를 Typing할 수 있었다

        하지만

        함수가 아니라 클래스에서 Generic 타입을 선언해줄 때는 표현하기가 어렵다

        따라서 Class에서 Generic 타입을 선언해줄 때는 TypeVar와 Generic을 같이 사용해주어서 표현할 수 있다

        # https://docs.python.org/3/library/typing.html#user-defined-generic-types
        
        from typing import TypeVar, Generic
        from logging import Logger
        
        T = TypeVar('T')
        
        
        class LoggedVar(Generic[T]):
            def __init__(self, value: T, name: str, logger: Logger) -> None:
                self.name = name
                self.logger = logger
                self.value = value
        
            def set(self, new: T) -> None:
                self.log('Set ' + repr(self.value))
                self.value = new
        
            def get(self) -> T:
                self.log('Get ' + repr(self.value))
                return self.value
        
            def log(self, message: str) -> None:
                self.logger.info('%s: %s', self.name, message)

        위 코드를 살펴 보면 Class의 get의 input ,set의 return 등이 __init__의 value 타입에 의존적이라는 것을 확인할 수 있다

         

        또한 해당 클래스를 input으로 받는 메소드를 구성해줄때는 Class[type]을 표시해서 특정 type을 지정해줄 수 있다

        위의 코드를 input으로 활용하는 메소드를 예시로 작성해보면 다음과 같다

         

         

        # https://docs.python.org/3/library/typing.html#user-defined-generic-types
        
        from collections.abc import Iterable
        
        def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None:
            for var in vars:
                var.set(0)

         

        또한 Pytorch의 DataLoader가 이러한 방식을 활용한 Class이다

         

        GitHub - pytorch/pytorch: Tensors and Dynamic neural networks in Python with strong GPU acceleration

        Tensors and Dynamic neural networks in Python with strong GPU acceleration - GitHub - pytorch/pytorch: Tensors and Dynamic neural networks in Python with strong GPU acceleration

        github.com

        ...
        T = TypeVar('T')
        T_co = TypeVar('T_co', covariant=True)
        
        class DataLoader(Generic[T_co]):
            r"""
            Data loader. Combines a dataset and a sampler, and provides an iterable over
            the given dataset.
        
            The :class:`~torch.utils.data.DataLoader` supports both map-style and
            iterable-style datasets with single- or multi-process loading, customizing
            loading order and optional automatic batching (collation) and memory pinning.
        
            See :py:mod:`torch.utils.data` documentation page for more details.
        
            Args:
        
        ...

        여기서 T_co 와 T의 차이점은 TypeVar의  covariant True 여부이다

        covariant에 대한 참고 자료

         

        Python’s covariance and contravariance

        (Many of the examples present are based on or from PEP 484)

        blog.magrathealabs.com

         

        4. typing.ParamSpec

        ParamSpec은 Callable의 인자를 다른 Callable의 인자로 넘겨 줄 때 사용한다

        from typing import TypeVar, Callable, ParamSpec
        import logging
        
        
        T = TypeVar('T')
        P = ParamSpec('P')
        
        
        def add_logging(f: Callable[P, T]) -> Callable[P, T]:
            '''A type-safe decorator to add logging to a function.'''
            def inner(*args: P.args, **kwargs: P.kwargs) -> T:
                logging.info(f'{f.__name__} was called')
                return f(*args, **kwargs)
            return inner
        
        
        @add_logging
        def add_two(x: float, y: float) -> float:
            '''Add two numbers together.'''
            return x + y
        
        
        @add_logging
        def send_msg(msg: str) -> None:
            print(f"I Sent {msg}")

         

        쉽게 말해서 위의 코드의 add_logging의 내부 함수인 inner에 P.args와 P.kwargs를 지정해주면

        아래에 add_two, send_msg에 데코레이터로 활용을 할때 해당 함수 인자의 타입을 받아 올 수 있는 것이다

         

        이 기능은 파이썬  3.10 이상부터 사용할 수 있다고 한다

         

         

         

        추가 DOC

         

        typing — Support for type hints

        Source code: Lib/typing.py This module provides runtime support for type hints. The most fundamental support consists of the types Any, Union, Callable, TypeVar, and Generic. For a specification, p...

        docs.python.org

         

         

        PEP 484 – Type Hints | peps.python.org

        PEP 484 – Type Hints Author: Guido van Rossum , Jukka Lehtosalo , Łukasz Langa BDFL-Delegate: Mark Shannon Discussions-To: Python-Dev list Status: Final Type: Standards Track Topic: Typing Created: 29-Sep-2014 Python-Version: 3.5 Post-History: 16-Jan-20

        peps.python.org

         

        '[CS] > 파이썬 🖤' 카테고리의 다른 글

        [파이썬 - 알쓸신잡] 왜 Dict는 List 보다 빠를까?  (0) 2023.06.12
        [CS]CPU bound vs. I/O bound  (0) 2023.06.08
        [Python] Typing 1편  (0) 2023.05.30
        [Python] Iterator vs. Generator  (0) 2023.03.14
        [Python] 파이썬 데코레이터  (0) 2022.12.27
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바