i take one breath / mint at a time

python typehints draft

#python #devstudy #datatypes

yes its good practice, it allows python and editors to make your life easier
used for the reader, and for linters

used in classes

but for example, if I were to pass a class instance in there without the type hint, I wouldnt know what methods I can access, however with the type hints it will give me these options. (editor sepcific)

class Test:
    def __init__(self):
        self.test = False

def func(x : Test):
  print(x.test)

t = Test()
func(t)

example of type error

class MyClass:
    a: int
    b: str
    c: float

    def __init__(self, a: float, b: list[int], c: dict[str, str]) -> None:
        self.a = a
        self.b = b
        self.c = c

examples of type hints

x: int
s: str
l: list
l2: list[str]
t: tuple[]
t2: tuple[int]
t3: tuple[int, ...]
d: dict
d2: dict[str, int]
etc...

typehint with a return:

def func(x: int, y: int) -> int:
  return x + y

for tuples, you need to declare the type

so this will cause a linter alert because if you don't use ... you're declaring a fixed length

my_tuple: tuple[int] = (1, 2)

but this will work (for tuples)

my_tuple2: tuple[int, int] = (1, 2)
my_tuple3: tuple[int, ...] = (1, 2, 5, 1, 7, 1, 8, 1)

Protocol??

class Test:
test: bool
def init(self) –> None:
self.test = False

def func(x: Test) –> None:
print(x.test)

t: Test = Test()
func(t)

Seperating typehints with initializations

also note that you can seperate typehints and initializations

type aliases

Coord = tuple[int, int]

def func(x: int, y: int) -> Coord:
  return (x, y)

Using TypeVar

a typevar is a type that is defined at call of the function
and you can use that typevar to ensure multiple variables are of the same type by the linter
it is also what will get assigned to a return value
typevars get super fun with bindings, covariants, and generics

from typing import TypeVar

T = TypeVar("T")

def foo(x: T) -> None:
    m: T
    if isinstance(x, int):
        m = 1
    else:
        m = True

for m: T in above function
it only assigns its type
so any assignment of m later in the function will be bound to that type
because there is no memory given to m
it's not like int x; in C++ for example

add example of without the typeVar

x: int
print(x)

gives NameError – why

this is NOT valid:

from typing import TypeVar, Generic

T = TypeVar("T")

class Foo(Generic[T]):
    thing: T