@@ -34,7 +34,9 @@ Useful built-in types
3434
3535.. code-block :: python
3636
37- # For most types, just use the name of the type
37+ # For most types, just use the name of the type.
38+ # Note that mypy can usually infer the type of a variable from its value,
39+ # so technically these annotations are redundant
3840 x: int = 1
3941 x: float = 1.0
4042 x: bool = True
@@ -100,12 +102,18 @@ Functions
100102 def show (value : str , excitement : int = 10 ) -> None :
101103 print (value + " !" * excitement)
102104
105+ # Note that arguments without a type are dynamically typed (treated as Any)
106+ # and that functions without any annotations not checked
107+ def untyped (x ):
108+ x.anything() + 1 + " string" # no errors
109+
103110 # This is how you annotate a callable (function) value
104111 x: Callable[[int , float ], float ] = f
112+ def register (callback : Callable[[str ], int ]) -> None : ...
105113
106114 # A generator function that yields ints is secretly just a function that
107115 # returns an iterator of ints, so that's how we annotate it
108- def g (n : int ) -> Iterator[int ]:
116+ def gen (n : int ) -> Iterator[int ]:
109117 i = 0
110118 while i < n:
111119 yield i
@@ -143,38 +151,57 @@ Classes
143151
144152.. code-block :: python
145153
146- class MyClass :
147- # You can optionally declare instance variables in the class body
148- attr: int
149- # This is an instance variable with a default value
150- charge_percent: int = 100
151-
154+ class BankAccount :
152155 # The "__init__" method doesn't return anything, so it gets return
153156 # type "None" just like any other method that doesn't return anything
154- def __init__ (self ) -> None :
155- ...
157+ def __init__ (self , account_name : str , initial_balance : int = 0 ) -> None :
158+ # mypy will infer the correct types for these instance variables
159+ # based on the types of the parameters.
160+ self .account_name = account_name
161+ self .balance = initial_balance
156162
157163 # For instance methods, omit type for "self"
158- def my_method (self , num : int , str1 : str ) -> str :
159- return num * str1
164+ def deposit (self , amount : int ) -> None :
165+ self .balance += amount
166+
167+ def withdraw (self , amount : int ) -> None :
168+ self .balance -= amount
160169
161170 # User-defined classes are valid as types in annotations
162- x: MyClass = MyClass()
171+ account: BankAccount = BankAccount(" Alice" , 400 )
172+ def transfer (src : BankAccount, dst : BankAccount, amount : int ) -> None :
173+ src.withdraw(amount)
174+ dst.deposit(amount)
175+
176+ # Functions that accept BankAccount also accept any subclass of BankAccount!
177+ class AuditedBankAccount (BankAccount ):
178+ # You can optionally declare instance variables in the class body
179+ audit_log: list[str ]
180+ # This is an instance variable with a default value
181+ auditor_name: str = " The Spanish Inquisition"
182+
183+ def __init__ (self , account_name : str , initial_balance : int = 0 ) -> None :
184+ super ().__init__ (account_name, initial_balance)
185+ self .audit_log: list[str ] = []
186+
187+ def deposit (self , amount : int ) -> None :
188+ self .audit_log.append(f " Deposited { amount} " )
189+ self .balance += amount
190+
191+ def withdraw (self , amount : int ) -> None :
192+ self .audit_log.append(f " Withdrew { amount} " )
193+ self .balance -= amount
163194
164- # You can also declare the type of an attribute in "__init__"
165- class Box :
166- def __init__ (self ) -> None :
167- self .items: list[str ] = []
195+ audited = AuditedBankAccount(" Bob" , 300 )
196+ transfer(audited, account, 100 ) # type checks!
168197
169198 # You can use the ClassVar annotation to declare a class variable
170199 class Car :
171200 seats: ClassVar[int ] = 4
172201 passengers: ClassVar[list[str ]]
173202
174203 # If you want dynamic attributes on your class, have it
175- # override "__setattr__" or "__getattr__":
176- # - "__getattr__" allows for dynamic access to names
177- # - "__setattr__" allows for dynamic assignment to names
204+ # override "__setattr__" or "__getattr__"
178205 class A :
179206 # This will allow assignment to any A.x, if x is the same type as "value"
180207 # (use "value: Any" to allow arbitrary types)
0 commit comments