๐Ÿ“Python ์œ ํ˜• ๋ฉ”๋ชจโ€Š๐Ÿ“-โ€Š์™œ ์ž๊พธ ์จ์š”?


Python์€ ๋™์  ์œ ํ˜• ์–ธ์–ด๋กœ ์„œ๋กœ ๋‹ค๋ฅธ ์œ ํ˜•์˜ ๋ณ€์ˆ˜๋ฅผ ์ƒ๋‹นํžˆ ์ž์œ ๋กญ๊ฒŒ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.๊ทธ๋Ÿฌ๋‚˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ, ์šฐ๋ฆฌ๋Š” ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์–ด๋–ค ์œ ํ˜•์˜ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ธ์ง€๋ฅผ ๊ฐ€์ •ํ•œ๋‹ค. (์ด๊ฒƒ์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‚˜ ์—…๋ฌด ๋…ผ๋ฆฌ์˜ ์ œํ•œ์œผ๋กœ ์ธํ•œ ๊ฒƒ์ผ ์ˆ˜๋„ ์žˆ๋‹ค.)ํ”„๋กœ๊ทธ๋žจ์ด ์ •ํ™•ํ•˜๊ฒŒ ์ž‘๋™ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ „์†ก ์˜ค๋ฅ˜ ์œ ํ˜•์˜ ๋ฐ์ดํ„ฐ์™€ ๊ด€๋ จ๋œ ์˜ค๋ฅ˜๋ฅผ ๋นจ๋ฆฌ ๋ฐœ๊ฒฌํ•˜๋Š” ๊ฒƒ์ด ์šฐ๋ฆฌ์—๊ฒŒ ๋งค์šฐ ์ค‘์š”ํ•˜๋‹ค.
์œ ์ง€ํ•˜๋‹คโ€‹โ€‹Python(3.6+) ํ˜„๋Œ€ ๋ฒ„์ „์˜ ๋™์  duck ํ˜•์‹์€ ๋ณ€์ˆ˜ ํ˜•์‹, ํด๋ž˜์Šค ํ•„๋“œ, ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ๋ฐ˜ํ™˜ ๊ฐ’์— ๋Œ€ํ•œ ์ฃผ์„์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹คโ€‹โ€‹ํ•จ์ˆ˜ ์ˆ˜๋Ÿ‰:
  • PEP 3107โ€Š-โ€ŠFunction Annotations
  • PEP 484โ€Š-โ€ŠType Hints
  • PEP 526โ€Š-โ€ŠSyntax for Variable Annotations
  • typing ํŒจํ‚ค์ง€
  • ํ˜•์‹ ์ฃผ์„์€ Python ํ•ด์„๊ธฐ์—์„œ ์ฝ์œผ๋ฉฐ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ๋„ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์ง€๋งŒ ์ œ3์ž ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ฃผ๋กœ ์ •์  ๋ถ„์„๊ธฐ๋ฅผ ์œ„ํ•ด ์„ค๊ณ„๋˜์—ˆ๋‹ค.
    ๋ณธ๊ณ ์—์„œ ๋‚˜๋Š” ์œ ํ˜• ์ฃผ์„์„ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ์ดˆ ์ง€์‹๊ณผ ์˜ˆ์‹œ๋ฅผ ์„ค๋ช…ํ•˜๊ณ  ์ตœ์ข…์ ์œผ๋กœ ๊ทธ๊ฒƒ์ด ์™œ ๋‚˜๋ฅผPython ๊ฐœ๋ฐœ์ž๋กœ์„œ์˜ ์ƒํ™œ์„ ๋”์šฑ ์‰ฝ๊ฒŒ ํ•˜๋Š”์ง€ ์„ค๋ช…ํ•˜๊ณ  ์‹ถ๋‹ค๐Ÿ™‚.
    ์šฐ์„  ์œ ํ˜• ์ฃผ์„์ด ๋ฌด์—‡์ธ์ง€ ์•Œ์•„๋ณด์ž

    โ–ถ ์œ ํ˜• ๋ฉ”๋ชจโ€Š-โ€Š๊ธฐ์ดˆ ์ง€์‹


    ์œ ํ˜• ์ž์ฒด๋Š” ๋ณ€์ˆ˜์˜ ๊ธฐ๋ณธ ์œ ํ˜•์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • str
  • int
  • float
  • bool
  • complex
  • bytes
  • ๋“ฑ
  • ์ด์ „ ๋ฒ„์ „์˜Python๊ณผ ๋‹ฌ๋ฆฌ ํ˜•์‹ ์ฃผ์„์€ ์ฃผ์„์ด๋‚˜docstring์œผ๋กœ ์ž‘์„ฑ๋œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ฝ”๋“œ์—์„œ ์ง์ ‘ ์ž‘์„ฑ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.ํ•œํŽธ, ์ด๊ฒƒ์€ ๋’ค๋กœ ํ˜ธํ™˜์„ฑ์„ ํŒŒ๊ดดํ–ˆ๋‹ค.๋‹ค๋ฅธ ํ•œํŽธ, ์ด๊ฒƒ์€ ๋ถ„๋ช…ํžˆ ์ฝ”๋“œ์˜ ์ผ๋ถ€๋ถ„์œผ๋กœ ์ƒ์‘ํ•˜๋Š” ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.
    ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ์ƒํ™ฉ์—์„œ ์ฃผ์„์€ ์ง์ ‘ ์˜ˆ์ƒํ•œ ์œ ํ˜•์„ ํฌํ•จํ•œ๋‹ค.๋‹ค์Œ์€ ๋”์šฑ ๋ณต์žกํ•œ ์ƒํ™ฉ์„ ํ† ๋ก ํ•  ๊ฒƒ์ด๋‹ค.๊ธฐ๋ณธ ํด๋ž˜์Šค๋ฅผ ์ฃผ์„์œผ๋กœ ์ง€์ •ํ•˜๋ฉด ํ•˜์œ„ ํ•ญ๋ชฉ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ’์œผ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.๋‹จ, ๊ธฐ๋ณธ ํด๋ž˜์Šค์—์„œ๋งŒ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    ๋ณ€์ˆ˜ ์ฃผ์„์€ ํ‘œ์ง€๋ถ€ ๋’ค์— ์‚ฌ์นญ์œผ๋กœ ์“ฐ์ธ๋‹ค.๊ทธ๋ฆฌ๊ณ  ๊ฐ’์„ ์ดˆ๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.์˜ˆ:
    price: int = 5
    title: "str"
    
    ํ•จ์ˆ˜ ๋งค๊ฐœ ๋ณ€์ˆ˜์˜ ์ฃผ์„ ๋ฐฉ์‹์€ ๋ณ€์ˆ˜์™€ ๊ฐ™๊ณ  ๋ฐ˜ํ™˜ ๊ฐ’์€ ํ™”์‚ดํ‘œ-> ์ดํ›„์™€ ์ฝœ๋ก  ๋’ค์— ์ง€์ •๋ฉ๋‹ˆ๋‹ค.python ํ•จ์ˆ˜์— ํ˜•์‹ ์ฃผ์„์„ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์‹œ๋ฅผ ๋“ค๊ฒ ์Šต๋‹ˆ๋‹ค.
    def func(a: int, b: float) -> str:
        a: str = f"{a}, {b}"
        return a
    
    ํด๋ž˜์Šค ํ•„๋“œ์— ๋Œ€ํ•ด ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•  ๋•Œ ์ฃผ์„์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.๊ทธ๋Ÿฌ๋‚˜ ๋ถ„์„๊ธฐ๋Š” __init__ ๋ฐฉ๋ฒ•์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ ์ถ”์ •ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด ๊ฒฝ์šฐ ์‹คํ–‰ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
    class Book:
        title: "str"
        author: str
    
        def __init__(self, title: "str, author: str) -> None:"
            self.title = title
            self.author = author
    
    b: Book = Book(title="Fahrenheit 451", author="Bradbury")
    

    โ–ถ ์œ ํ˜• ๋ฉ”๋ชจโ€Š-โ€Š๋‚ด์žฅ ์œ ํ˜•


    ํ‘œ์ค€ ์œ ํ˜•์„ ์ฃผ์„์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ชจ๋“ˆtyping์—๋Š” ์œ ์šฉํ•œ ๊ฒƒ๋“ค์ด ๋งŽ์ด ์ˆจ๊ฒจ์ ธ ์žˆ๋‹ค.๊ทธ๊ฒƒ์˜ ํ•˜์œ„ ๋ชจ๋“ˆ์„ ๋ด…์‹œ๋‹ค.

    ์ผ.๏ธโƒฃ ์„ ํƒ ๊ฐ€๋Šฅ


    ์œ ํ˜•int์œผ๋กœ ๋ณ€์ˆ˜๋ฅผ ํ‘œ์‹œํ•˜๊ณ  None ๊ฐ’์„ ์ง€์ •ํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

    Incompatible types in assignment (expression has type "None", variable has type "int")


    ์ด ๊ฒฝ์šฐ ์ž…๋ ฅ ๋ชจ๋“ˆ์€ ํŠน์ • ์œ ํ˜•์„ ํ‘œ์‹œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์„ค๋ช…Optional์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.์„ ํƒ์  ๋ณ€์ˆ˜์˜ ์œ ํ˜•์€ ๋Œ€๊ด„ํ˜ธ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
    from typing import Optional
    
    amount: int
    amount: None # Gives "Incompatible types" error
    
    price: Optional[int]
    price: None # Will work!
    

    ์ด.๏ธโƒฃ ์–ด๋–ค


    ๋•Œ๋•Œ๋กœ ๋ณ€์ˆ˜์˜ ๊ฐ€๋Šฅํ•œ ์œ ํ˜•์„ ์ œํ•œํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.์˜ˆ๋ฅผ ๋“ค์–ด, ๋งŒ์•ฝ ์ด๊ฒƒ์ด ์ •๋ง ์ค‘์š”ํ•˜์ง€ ์•Š๋‹ค๋ฉด, ํ˜น์€ ๋‹ค๋ฅธ ์œ ํ˜•์˜ ์ฒ˜๋ฆฌ๋ฅผ ๊ณ„ํšํ•˜๊ณ  ์žˆ๋‹ค๋ฉด.์ด ๊ฒฝ์šฐ ์ฃผ์„Any์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.๋‹ค์Œ ์ฝ”๋“œ์— ๋Œ€ํ•ด ๋งน์„ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    some_item: Any = 1
    print(some_item)
    print(some_item.startswith("hello"))
    print(some_item // 0)
    
    ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์™œ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒobject?๊ทธ๋Ÿฌ๋‚˜ ์ด ๊ฒฝ์šฐ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ธ์Šคํ„ด์Šค๋กœ๋งŒ ๊ฐ„์ฃผํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹คobject.
    some_object: object
    print(some_object)
    print(some_object.startswith("hello)) # ERROR: "object" has no attribute "startswith"
    
    print(some_object // 0) # ERROR: Unsupported operand types for // ("object" and "int")
    

    ์‚ผ.๏ธโƒฃ ํ˜‘ํšŒ


    ๋ชจ๋“  ์œ ํ˜•์ด ์•„๋‹Œ ์ผ๋ถ€ ์œ ํ˜•๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์ฃผ์„typing.Union์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ด„ํ˜ธ์˜ ์œ ํ˜• ๋ชฉ๋ก์„ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    def hundreds(x: Union[int, float]) -> int:
        return (int(x) // 100) % 100
    
    hundreds(100.0)
    hundreds(100)
    hundreds("100")
    # ERROR: Argument 1 to "hundreds" has incompatible type "str"; expected "Union[int, float]"
    
    ์ฐธ๊ณ ๋กœ ์ฃผ์„Optional[T]์€ Union[T, None]๊ณผ ๊ฐ™๋‹ค. ๋น„๋ก ์ด๋Ÿฐ ๊ธฐํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•˜์ง€๋Š” ์•Š์ง€๋งŒ.

    ์‚ฌ.๏ธโƒฃ ์†Œ์žฅํ•˜๋‹ค


    ์œ ํ˜• ์ฃผ์„ ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ ๋ฒ”์šฉ ๋ฉ”์ปค๋‹ˆ์ฆ˜PEP484โ€Š-โ€ŠGenerics์„ ์ง€์›ํ•˜๋ฉฐ, ์ž์„ธํ•œ ์ •๋ณด๋Š” ๋ณธ๊ณ ์˜ ๋‘ ๋ฒˆ์งธ ๋ถ€๋ถ„์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ์ด ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ ์šฉ๊ธฐ์— ๋ฒ”์šฉ์— ์ €์žฅ๋œ ์š”์†Œ ์œ ํ˜•์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์˜ค.๏ธโƒฃ ๋ชฉ๋ก


    ๋ณ€์ˆ˜์— ๋ชฉ๋ก์ด ์žˆ์Œ์„ ํ‘œ์‹œํ•˜๋ ค๋ฉด ๋ชฉ๋ก ์œ ํ˜•์„ ์ฃผ์„์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.๊ทธ๋Ÿฌ๋‚˜ ๋ชฉ๋ก์— ์–ด๋–ค ์š”์†Œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ์ง€์ •ํ•˜๋ ค๋ฉด ์ด๋Ÿฌํ•œ ์ฃผ์„์€ ๋” ์ด์ƒ ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.์ด๋ฅผ ์œ„ํ•ดtyping.List๊ฐ€ ์žˆ๋‹ค.์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ณ€์ˆ˜ ํ˜•์‹์„ ์ง€์ •ํ•˜๋Š” ๋ฐฉ์‹๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ด„ํ˜ธ์— ๋ชฉ๋ก ํ•ญ๋ชฉ์˜ ํ˜•์‹์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
    titles: List[str] = ["hello", "world"]
    titles.append(100500)
    # ERROR: Argument 1 to "hundreds" has incompatible type "str"; expected "Union[int, float]"
    
    titles = ["hello", 1]
    # ERROR: List item 1 has incompatible type "int"; expected "str"
    
    items: List = ["hello", 1]
    # Everything is good!
    
    ์ด ๋ชฉ๋ก์— ๋ถˆํ™•์‹คํ•œ ์ˆ˜๋Ÿ‰์˜ ์œ ์‚ฌํ•œ ํ•ญ๋ชฉ์ด ํฌํ•จ๋˜์–ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์‹ญ์‹œ์˜ค.๊ทธ๋Ÿฌ๋‚˜ ์ฃผ์„ ์š”์†Œ์—๋Š” ์ œํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค. Any, Optional, List ๋ฐ ๊ธฐํƒ€ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.์š”์†Œ ์œ ํ˜•์ด ์ง€์ •๋˜์ง€ ์•Š์œผ๋ฉด Any ๋กœ ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.
    ๋ชฉ๋ก ์™ธ์— ์œ ์‚ฌํ•œ ์ง‘ํ•ฉ ์ฃผ์„๋„ ์žˆ์Šต๋‹ˆ๋‹ค: typing.Set๊ณผtyping.FrozenSet.

    ์œก.๏ธโƒฃ ๋‹ค์ค‘ ๊ทธ๋ฃน


    ๋ชฉ๋ก๊ณผ ๋‹ฌ๋ฆฌ ๋ฉ”ํƒ€๊ทธ๋ฃน์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค๋ฅธ ์œ ํ˜•์˜ ์š”์†Œ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.๋ฌธ๋ฒ•์€ ๋น„์Šทํ•˜์ง€๋งŒ ํ•œ ๊ฐ€์ง€ ๋‹ค๋ฅด๋‹ค. ์›์กฐ์˜ ๊ฐ ์š”์†Œ์˜ ์œ ํ˜•์€ ๊ฐ๊ฐ ๋„ค๋ชจ๋‚œ ๊ด„ํ˜ธ๋กœ ํ‘œ์‹œ๋œ๋‹ค.
    ๋ชฉ๋ก๊ณผ ์œ ์‚ฌํ•œ ๋ฉ”ํƒ€๊ทธ๋ฃน์„ ์‚ฌ์šฉํ•  ๊ณ„ํš์ธ ๊ฒฝ์šฐ ์•Œ ์ˆ˜ ์—†๋Š” ์ˆ˜์˜ ๋™์ผํ•œ ์œ ํ˜•์˜ ์š”์†Œ๋ฅผ ์ €์žฅํ•˜๋ ค๋ฉด ์ƒ๋žต ๋ฒˆํ˜ธ ... ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    ์—”ํ‹ฐํ‹ฐ ์œ ํ˜•์„ ์ง€์ •ํ•˜์ง€ ์•Š๋Š” ๋ฉ”๋ชจTuple๋Š” Tuple[Any,ย ...]์™€ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
    price_container: Tuple[int] = (1,)
    price_container: ("hello")
    # ERROR: Incompatible types in assignment (expression has type "str", variable has type "Tuple[int]")
    
    price_container = (1, 2)
    # ERROR: Incompatible types in assignment (expression has type "Tuple[int, int]", variable has type "Tuple[int]")
    
    price_with_title: Tuple[int, str] = (1, "hello")
    # Everything is good!
    
    prices: Tuple[int, ...] = (1, 2)
    prices: (1,)
    prices: (1, "str")
    # ERROR: Incompatible types in assignment (expression has type "Tuple[int, str]", variable has type "Tuple[int]")
    
    something: Tuple = (1, 2, "hello")
    # Everything is good!
    

    ์น .๏ธโƒฃ ์‚ฌ์ „


    ์‚ฌ์ „typing.Dict์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.ํ‚ค ์œ ํ˜•๊ณผ ๊ฐ’ ์œ ํ˜•์— ๋Œ€ํ•œ ์„ค๋ช…์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
    book_authors: Dict[str, str] = {"Fahrenheit 451": "Bradbury"}
    book_authors["1984"] = 0
    # ERROR: Incompatible types in assignment (expression has type "int", target has type "str")
    
    book_authors[1984] = "Orwell"
    # ERROR: Invalid index type "int" for "Dict[str, str]"; expected type "str"
    
    ์œ ์‚ฌ ์‚ฌ์šฉtyping.DefaultDict ๋ฐ typing.OrderedDict

    ํŒ”.๏ธโƒฃ ํ•จ์ˆ˜ ์‹คํ–‰ ๊ฒฐ๊ณผ


    ๋ชจ๋“  ์ข…๋ฅ˜์˜ ์ฃผ์„์€ ํ•จ์ˆ˜ ๊ฒฐ๊ณผ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ํ˜•์‹์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.ํ•˜์ง€๋งŒ ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค.
    ํ•จ์ˆ˜๊ฐ€ ๊ฒฐ๊ณผ (์˜ˆ: how print ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ฒฐ๊ณผ๋Š” ํ•ญ์ƒ ๊ฐ™์Šต๋‹ˆ๋‹ค None.์šฐ๋ฆฌ๋Š” ๋˜ํ•œ ์ฃผ์„None์„ ์‚ฌ์šฉํ•œ๋‹ค.
    ์ด๋Ÿฌํ•œ ํ•จ์ˆ˜๋ฅผ ์™„์„ฑํ•˜๋Š” ์˜ฌ๋ฐ”๋ฅธ ์˜ต์…˜์€ ๋ช…์‹œ์  ๋ฐ˜ํ™˜None, ์ง€์ •๋˜์ง€ ์•Š์€ ๊ฐ’์˜ ๋ฐ˜ํ™˜ ๋ฐ ํ˜ธ์ถœ๋˜์ง€ ์•Š์€ ์ข…๋ฃŒreturn์ž…๋‹ˆ๋‹ค.
    def nothing(a: int) -> None:
        if a == 1:
            return
        elif a == 2:
            return
        elif a == 3:
            return "" # No return value expected
        else:
            pass
    
    
    ํ•จ์ˆ˜๊ฐ€ ์ œ์–ด๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ (์˜ˆ: how sys.exit ๋ฉ”๋ชจ NoReturn ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    def forever() -> NoReturn:
        while True:
            pass
    
    ๋งŒ์•ฝ ์ด๊ฒƒ์ด ์ƒ์„ฑ ํ•จ์ˆ˜, ์ฆ‰ ๊ทธ ์ฃผ์ฒด์— ์—ฐ์‚ฐ์ž yield๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค๋ฉด, ๋˜๋Œ์•„์˜ค๋Š” ํ•จ์ˆ˜Iterable[T]์— ๋Œ€ํ•ด ์ฃผ์„Generator[YT, ST, RT]์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    def generate_two() -> Iterable[int]:
        yield 1
        yield "2"
        # ERROR: Incompatible types in "yield" (actual type "str", expected type "int")
    

    ๊ฒฐ๋ก ์ด ์•„๋‹ˆ๋ผ


    ๋งŽ์€ ๊ฒฝ์šฐ์— ์œ ํ˜• ๋ชจ๋“ˆ์€ ์ ๋‹นํ•œ ์œ ํ˜•์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ, ๋‚˜๋Š” ๋ชจ๋“  ๋‚ด์šฉ์„ ํฌํ•จํ•˜์ง€ ์•Š๋Š”๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ทธ ํ–‰์œ„๋Š” ๋ฌ˜์‚ฌํ•œ ๊ฒƒ๊ณผ ์œ ์‚ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.์˜ˆ๋ฅผ ๋“ค์–ด, Iterator ์€ collections.abc.Iterator, typing.SupportsInt ์˜ ๊ณตํ†ต ๋ฒ„์ „์œผ๋กœ, ๋Œ€์ƒ ์ง€์› ๋ฐฉ๋ฒ•__int__ ๋˜๋Š” Callable ์ง€์› ๋ฐฉ๋ฒ•__call__ ์˜ ํ•จ์ˆ˜์™€ ๋Œ€์ƒ์„ ํ‘œ์‹œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค
    ์ด ํ‘œ์ค€์€ ์ •์  ๋ถ„์„๊ธฐ์˜ ์ •๋ณด๋งŒ ํฌํ•จํ•˜๋Š” ์ฃผ์„๊ณผ ๋ฉ”๋ชจ๋ฆฌ ํŒŒ์ผ ํ˜•์‹์œผ๋กœ ์ฃผ์„์˜ ํ˜•์‹์„ ์ •์˜ํ–ˆ๋‹ค.

    ์ž์„ธํžˆ ๋ณด๊ธฐ


    ์ด ๋ฌธ์„œ๊ฐ€ ๋„์›€์ด ๋œ๋‹ค๋ฉด๐Ÿ’š ๋˜๋Š”๐Ÿ‘ ์•„๋ž˜ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ฑฐ๋‚˜ ํŽ˜์ด์Šค๋ถ์— ์ด ๊ธ€์„ ๊ณต์œ ํ•˜๋ฉด ์นœ๊ตฌ๋„ ์ด์ต์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
    https://subscribe.to/raevskymichail

    ์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ