@@ -34,7 +34,9 @@ Useful built-in types
34
34
35
35
.. code-block :: python
36
36
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
38
40
x: int = 1
39
41
x: float = 1.0
40
42
x: bool = True
@@ -100,12 +102,18 @@ Functions
100
102
def show (value : str , excitement : int = 10 ) -> None :
101
103
print (value + " !" * excitement)
102
104
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
+
103
110
# This is how you annotate a callable (function) value
104
111
x: Callable[[int , float ], float ] = f
112
+ def register (callback : Callable[[str ], int ]) -> None : ...
105
113
106
114
# A generator function that yields ints is secretly just a function that
107
115
# 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 ]:
109
117
i = 0
110
118
while i < n:
111
119
yield i
@@ -143,38 +151,57 @@ Classes
143
151
144
152
.. code-block :: python
145
153
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 :
152
155
# The "__init__" method doesn't return anything, so it gets return
153
156
# 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
156
162
157
163
# 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
160
169
161
170
# 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
163
194
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!
168
197
169
198
# You can use the ClassVar annotation to declare a class variable
170
199
class Car :
171
200
seats: ClassVar[int ] = 4
172
201
passengers: ClassVar[list[str ]]
173
202
174
203
# 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__"
178
205
class A :
179
206
# This will allow assignment to any A.x, if x is the same type as "value"
180
207
# (use "value: Any" to allow arbitrary types)
0 commit comments