├── README.md ├── img ├── py │ ├── rebind.png │ └── uniencode.png └── tinypy310-iso.png └── python310.rst /README.md: -------------------------------------------------------------------------------- 1 | 2 | Tiny Python 3.10 Notebook 3 | ======================== 4 | 5 | This repository contains the text for the *Tiny Python 3.10 Notebook*. 6 | 7 | 8 | 9 | Warning, this is not an introduction to Python. Rather it is a notebook 10 | containing curated examples for Python 3 as well as the new features 11 | found in Python 3.10. It is designed to accompany technical corporate 12 | training offered by the author or aid those who want a quick refresher 13 | to the Python syntax. 14 | 15 | Reviews 16 | --------- 17 | 18 | > I love these little books, and have several versions across multiple languages. This is the latest in a series of succinct and up-to-date summaries of the syntax and idioms of Python, and have enough whitespace and notes pages to add useful additional information of snippets of code, lists of tricks etc that you pick up along the way. 19 | > 20 | > I also use these books as a neat little tool to wean me off looking at my phone in idle moments. This book is eminently pocketable and if it's like its siblings it takes a battering as well (witness my ES6 book after nearly three years of riding around in my pocket). 21 | > 22 | > I tend to view it as a pre-populated personal notebook, with enough room for embellishment. The quality of the content and the book itself are excellent. I can't wait to start annotating this one, too! - Amazon 3.8 review 23 | 24 | These are for the 3.6 version of this book 25 | 26 | > This is an awesome python3 resource I share all the time. 🐍🎉 - @nnja (MS Developer Advocate) 27 | 28 | > I think it's pretty awesome. It's all of the syntax boiled down to just the facts man. - Brian Okken (Host of Test & Code podcast) 29 | 30 | 31 | > It's the perfect follow on to a training course. - Michael Kennedy (Host of Talk Python podcast) 32 | 33 | > Great Python reference book by @\_\_mharrison\_\_ "Tiny Python 3.6 Notebook" It's NOT a @ProjectJupyter notebook - @okeedoak 34 | 35 | > Goodness! So thankful for @\_\_mharrison\_\_ and his Tiny Python 3.6 Notebook. Great resource! Go get it… - @\_\_jamesssio\_\_ 36 | 37 | > Tiny #Python notebook for looking up all the basics. I found this a very concise read if you have some prev prog exp - @andreasose 38 | 39 | > Useful collection of notes on Python 3.6 - @hjelmj 40 | 41 | > Cool work: a tiny and handy notebook containing notes, tables and examples for Python 3.6. Very much recommended! - @epaillas 42 | 43 | > I keep a copy on my desk. Excellent resource - @HLIBIndustry 44 | 45 | > Awesome community work! - @MostafaElzoghbi 46 | 47 | > Интересный формат книги по #python - @ku_al 48 | 49 | Bulk Purchase 50 | --------------- 51 | 52 | If you are interested in purchasing larger amounts (100+) for schools, employees or for 53 | use as giveaways/swag at a conference (much better than a tshirt!), get in touch 54 | with Matt (matt at metasnake dot com). 55 | 56 | Thanks 57 | ------ 58 | 59 | If you enjoy this content, consider *purchasing the physical version [on Amazon](https://www.amazon.com/Tiny-Python-3-9-Notebook-Examples/dp/B08L4QWL9H/ref=sr_1_2?crid=QYNIFZ7C3EQE&dchild=1&keywords=tiny+python+notebook&qid=1603324510&sprefix=tiny+python+note%2Caps%2C226&sr=8-2*) 60 | It is a hand laid out version that fits in the pocket and has blank 61 | pages in the back for note taking. Thanks! 62 | 63 | 64 | 65 | Feel free to share this repository on social media. 66 | 67 | Errors 68 | ------ 69 | 70 | The author is human and will certainly make errors. You may file a bug 71 | and it may be resolved in a future version of the book. I love feedback 72 | and would love to hear your ideas on what is missing or could be 73 | improved. 74 | 75 | License 76 | ------- 77 | 78 | This content is licensed under the 79 | Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 80 | 4.0) 81 | 82 | 83 | -------------------------------------------------------------------------------- /img/py/rebind.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattharrison/Tiny-Python-3.10-Notebook/5fcfeb4ff46c3e96f8fe3a3864b3b205f63a9821/img/py/rebind.png -------------------------------------------------------------------------------- /img/py/uniencode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattharrison/Tiny-Python-3.10-Notebook/5fcfeb4ff46c3e96f8fe3a3864b3b205f63a9821/img/py/uniencode.png -------------------------------------------------------------------------------- /img/tinypy310-iso.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattharrison/Tiny-Python-3.10-Notebook/5fcfeb4ff46c3e96f8fe3a3864b3b205f63a9821/img/tinypy310-iso.png -------------------------------------------------------------------------------- /python310.rst: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Introduction 5 | ============== 6 | 7 | This is not so much an instructional manual, but rather notes, tables, and 8 | examples for Python syntax. It was created by the author as an additional 9 | resource during training, meant to be distributed as a physical notebook. 10 | Participants (who favor the physical characteristics of dead tree material) 11 | could add their own notes, thoughts, and have a valuable reference 12 | of curated examples. 13 | 14 | 15 | Running Python 16 | ============== 17 | 18 | Installation 19 | --------------- 20 | 21 | To check if Python is installed, run the following from a terminal:: 22 | 23 | $ python3 --version 24 | 25 | 26 | Otherwise, install Python 3 from the website [#]_. 27 | 28 | .. [#] http://python.org 29 | 30 | Invoking Python 31 | --------------- 32 | 33 | The Python executable will behave differently depending on the command line options you give it: 34 | 35 | * Start the Python REPL:: 36 | 37 | $ python3 38 | 39 | * Execute the ``file.py`` file:: 40 | 41 | $ python3 file.py 42 | 43 | * Execute the ``file.py`` file, and drop into REPL with namespace of ``file.py``:: 44 | 45 | $ python3 -i file.py 46 | 47 | * Execute the ``json/tool.py`` module:: 48 | 49 | $ python3 -m json.tool 50 | 51 | * Execute ``"print('hi')"`` :: 52 | 53 | $ python3 -c "print('hi')" 54 | 55 | REPL 56 | ---- 57 | 58 | * Use the ``help`` function to read the documentation for a module/class/function. As a standalone invocation, 59 | you enter the help system and can explore various topics. 60 | * Use the ``dir`` function to list contents of the namespace, or attributes of an object if you pass one in. 61 | 62 | .. note:: 63 | 64 | The majority of code in this book is written as if it were executed in a REPL. If you 65 | are typing it in, ignore the primary and secondary prompts (``>>>`` and ``...``). 66 | 67 | The Zen of Python 68 | =================== 69 | 70 | Run the following in an interpreter to get an Easter egg that describes some of the ethos behind Python. This is also codified in PEP 20:: 71 | 72 | >>> import this 73 | The Zen of Python, by Tim Peters 74 | 75 | Beautiful is better than ugly. 76 | Explicit is better than implicit. 77 | Simple is better than complex. 78 | Complex is better than complicated. 79 | Flat is better than nested. 80 | Sparse is better than dense. 81 | Readability counts. 82 | Special cases aren't special enough to break the 83 | rules. 84 | Although practicality beats purity. 85 | Errors should never pass silently. 86 | Unless explicitly silenced. 87 | In the face of ambiguity, refuse the temptation 88 | to guess. 89 | There should be one --and preferably only one-- 90 | obvious way to do it. 91 | Although that way may not be obvious at first 92 | unless you're Dutch. 93 | Now is better than never. 94 | Although never is often better than *right* now. 95 | If the implementation is hard to explain, it's a 96 | bad idea. 97 | If the implementation is easy to explain, it may 98 | be a good idea. 99 | Namespaces are one honking great idea -- let's 100 | do more of those! 101 | 102 | These might just seem like silly one liners, but there is a lot of wisdom 103 | packed in here. It is good for Python programmers to review these 104 | every once in a while and see if these hold true for their code. (Or to 105 | justify their code reviews) 106 | 107 | Built-in Types 108 | =============== 109 | 110 | Variables 111 | --------- 112 | 113 | Python variables are like cattle tags, they point to objects (which can be 114 | classes, instances, modules, or functions), but variables are not the objects. You can 115 | reuse variable names for different object types (though you probably shouldn't):: 116 | 117 | >>> a = 400 # a points to an integer 118 | >>> a = '400' # a now points to a string 119 | 120 | 121 | .. note:: 122 | 123 | The ``#`` character denotes the start of a comment. There are no multi-line comments, though 124 | most editors with Python support can comment out a region. 125 | 126 | The figure that follows illustrates how everything is an object in Python and variables just point to them. 127 | 128 | 129 | .. figure:: img/py/rebind.png 130 | 131 | Illustration of reusing the same variable 132 | 133 | .. raw:: latex 134 | 135 | %\Needspace{5\baselineskip} 136 | \clearpage 137 | 138 | Assignment Expressions 139 | ---------------------- 140 | 141 | In Python 3.8 the *walrus operator* was introduced, ``:=``. The following code:: 142 | 143 | rows = connection.fetch(200) 144 | while rows: 145 | process(rows) 146 | rows = connection.fetch(200) 147 | 148 | Can be rewritten as:: 149 | 150 | while rows := connection.fetch(200): 151 | process(rows) 152 | 153 | Normal assignment statements cannot be put in ``if`` or ``while`` statements, but 154 | an assignment expression evaluates to the value of the variable, so it can. 155 | 156 | Numbers 157 | ----------- 158 | 159 | Python includes three types of numeric literals: 160 | *integers* (unlimited precision), *floats* (usually C ``double``, see ``sys.float_info``), and *complex numbers*. 161 | Python 3.6 added the ability to use underscores to 162 | improve readability (PEP 515):: 163 | 164 | >>> dollars = 3_283_999 165 | 166 | Floats in general are approximations, though since Python 3.1, they are rounded when they are displayed so that may mask the lack of precision to casual users. 167 | 168 | .. raw:: latex 169 | 170 | \Needspace{5\baselineskip} 171 | 172 | .. longtable: format: {r l} 173 | 174 | .. table:: Number types 175 | 176 | 177 | ================ =========================== 178 | Type Example 179 | ================ =========================== 180 | Integer ``14`` 181 | Integer (Hex) ``0xe`` 182 | Integer (Octal) ``0o16`` 183 | Integer (Binary) ``0b1110`` 184 | Float ``14.0`` 185 | Float ``1.4e1`` 186 | Complex ``14+0j`` 187 | Underscore ``1_000`` 188 | ================ =========================== 189 | 190 | There are many built-in functions for manipulating 191 | numbers ie. ``abs``, ``min``, ``max``, ``ceil``. 192 | Also see the ``math``, ``random``, and ``statistics`` modules in 193 | the standard library. See the ``fractions`` and ``decimal`` libraries in the standard library rational numbers and precise floating point numbers. 194 | 195 | 196 | .. longtable: format: {p{.3\textwidth} l >{\raggedright\arraybackslash}p{.3\textwidth}} 197 | 198 | .. longtable: format: {>{\hangindent=1em\hangafter=1 }p{.3\textwidth} l >{\hangindent=1em\hangafter=1 }p{.3\textwidth}} 199 | 200 | .. table:: Number magic methods 201 | 202 | ====================== ================== ===================================== 203 | Operation Provided By Result 204 | ====================== ================== ===================================== 205 | ``abs(num)`` ``__abs__`` Absolute value of ``num`` 206 | ``num + num2`` ``__add__`` Addition 207 | ``bool(num)`` ``__bool__`` Boolean conversion 208 | ``num == num2`` ``__eq__`` Equality 209 | ``float(num)`` ``__float__`` Float conversion 210 | ``num // num2`` ``__floordiv__`` Integer division 211 | ``num >= num2`` ``__ge__`` Greater or equal 212 | ``num > num2`` ``__gt__`` Greater than 213 | ``int(num)`` ``__int__`` Integer conversion 214 | ``num <= num2`` ``__le__`` Less or equal 215 | ``num < num2`` ``__lt__`` Less than 216 | ``num % num2`` ``__mod__`` Modulus 217 | ``num * num2`` ``__mul__`` Multiplication 218 | ``num != num2`` ``__ne__`` Not equal 219 | ``-num`` ``__neg__`` Negative 220 | ``+num`` ``__pos__`` Positive 221 | ``num ** num2`` ``__pow__`` Power 222 | ``round(num)`` ``__round__`` Round 223 | ``num.__sizeof__()`` ``__sizeof__`` Bytes for internal representation 224 | ``str(num)`` ``__str__`` String conversion 225 | ``num - num2`` ``__sub__`` Subtraction 226 | ``num / num2`` ``__truediv__`` Float division 227 | ``math.trunc(num)`` ``__trunc__`` Truncation 228 | ====================== ================== ===================================== 229 | 230 | See ``math.isclose`` and ``cmath.isclose`` for floating point equality testing. 231 | 232 | .. longtable: format: {p{.3\textwidth} l >{\raggedright\arraybackslash}p{.3\textwidth}} 233 | 234 | .. table:: Integer specific methods and operations 235 | 236 | ==================== ================== ===================================== 237 | Operation Provided By Result 238 | ==================== ================== ===================================== 239 | ``num & num2`` ``__and__`` Bitwise and 240 | ``math.ceil(num)`` ``__ceil__`` Ceiling 241 | ``math.floor(num)`` ``__floor__`` Floor 242 | ``~num`` ``__invert__`` Bitwise inverse 243 | ``num << num2`` ``__lshift__`` Left shift 244 | ``num | num2`` ``__or__`` Bitwise or 245 | ``num >> num2`` ``__rshift__`` Right shift 246 | ``num ^ num2`` ``__xor__`` Bitwise xor 247 | ``num.bit_length()`` ``bit_length`` Number of bits necessary 248 | ==================== ================== ===================================== 249 | 250 | .. longtable: format: {p{.4\textwidth} p{.5\textwidth}} 251 | 252 | .. table:: Float specific methods and operations 253 | 254 | ================================== ======================== 255 | Operation Result 256 | ================================== ======================== 257 | ``f.as_integer_ratio()`` Returns num, denom tuple 258 | ``f.is_integer()`` Boolean if whole number 259 | ``f.hex()`` Hex base 2 version 260 | ``float.fromhex(h)`` Convert above to float 261 | ================================== ======================== 262 | 263 | See IEEE 754 for how ``.as_integer_ratio`` works. See ``math.isclose`` for comparing float values. 264 | 265 | 266 | 267 | Strings 268 | ----------- 269 | 270 | Python 3 strings hold Unicode data. Python has a few ways to represent strings. There is also a bytes type (PEP 3137). Strings can be created using string literals or by passing an object, or bytes into ``str``:: 271 | 272 | >>> str(1) 273 | '1' 274 | 275 | 276 | .. raw:: latex 277 | 278 | \Needspace{10\baselineskip} 279 | 280 | 281 | .. longtable: format: {r l} 282 | 283 | .. table:: String types 284 | 285 | ================ =========================== 286 | Type Example 287 | ================ =========================== 288 | String ``"hello\tthere"`` 289 | String ``'hello'`` 290 | String ``'''He said, "hello"'''`` 291 | Raw string ``r'hello\tthere'`` 292 | Byte string ``b'hello'`` 293 | ================ =========================== 294 | 295 | .. longtable: format: {>{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.3\textwidth} >{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.6\textwidth}} 296 | 297 | .. table:: Escape Characters 298 | 299 | =================== ================= 300 | Escape Sequence Output 301 | =================== ================= 302 | ``\`` newline Ignore trailing newline in triple quoted string 303 | ``\\`` Backslash 304 | ``\'`` Single quote 305 | ``\"`` Double quote 306 | ``\a`` ASCII Bell 307 | ``\b`` ASCII Backspace 308 | ``\n`` Newline 309 | ``\r`` ASCII carriage return 310 | ``\t`` Tab 311 | ``\u12af`` Unicode 16 bit 312 | ``\U12af89bc`` Unicode 32 bit 313 | ``\N{BLACK STAR}`` Unicode name 314 | ``\o84`` Octal character 315 | ``\xFF`` Hex character 316 | =================== ================= 317 | 318 | 319 | 320 | .. longtable: format: {p{.3\textwidth} l >{\raggedright\arraybackslash}p{.3\textwidth}} 321 | 322 | 323 | .. longtable: format: {>{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.3\textwidth} l >{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.3\textwidth}} 324 | 325 | .. table:: String operations 326 | 327 | ============================= ========================= ========================================================== 328 | Operation Provided By Result 329 | ============================= ========================= ========================================================== 330 | ``s + s2`` ``__add__`` String concatenation 331 | ``"foo" in s`` ``__contains__`` Membership 332 | ``s == s2`` ``__eq__`` Equality 333 | ``s >= s2`` ``__ge__`` Greater or equal 334 | ``s[0]`` ``__getitem__`` Index operation 335 | ``s > s2`` ``__gt__`` Greater 336 | ``s <= s2`` ``__le__`` Less than or equal 337 | ``len(s)`` ``__len__`` Length 338 | ``s < s2`` ``__lt__`` Less than 339 | ``s % (1, 'foo')`` ``__mod__`` Formatting 340 | ``s * 3`` ``__mul__`` Repetition 341 | ``s != s2`` ``__ne__`` Not equal 342 | ``repr(s)`` ``__repr__`` Programmer friendly string 343 | ``s.__sizeof__()`` ``__sizeof__`` Bytes for internal representation 344 | ``str(s)`` ``__str__`` User friendly string 345 | ============================= ========================= ========================================================== 346 | 347 | 348 | .. longtable: format: {>{\hangindent=1em\hangafter=1 }p{.35\textwidth} p{.55\textwidth}} 349 | 350 | .. prevent header at bottom of page 351 | 352 | .. raw:: latex 353 | 354 | \Needspace{5\baselineskip} 355 | 356 | 357 | .. longtable: format: {>{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.3\textwidth} >{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.6\textwidth}} 358 | 359 | .. table:: String methods 360 | 361 | ======================================================= =========================================================== 362 | Operation Result 363 | ======================================================= =========================================================== 364 | ``s.capitalize()`` Capitalizes a string 365 | ``s.casefold()`` Lowercase in a unicode compliant manner 366 | ``s.center(w, [char])`` Center a string in ``w`` spaces with ``char`` (default ``" "``) 367 | ``s.count(sub, [start, [end]])`` Count ``sub`` in ``s`` between ``start`` and ``end`` 368 | ``s.encode(encoding, errors= 'strict')`` Encode a string into bytes 369 | ``s.endswith(sub)`` Check for a suffix 370 | ``s.expandtabs( tabsize=8)`` Replaces tabs with spaces 371 | ``s.find(sub, [start, [end]])`` Find substring or return ``-1`` 372 | ``s.format(*args, **kw)`` Format string 373 | ``s.format_map( mapping)`` Format strings with a mapping 374 | ``s.index(sub, [start, [end]])`` Find substring or raise ``ValueError`` 375 | ``s.isalnum()`` Boolean if alphanumeric 376 | ``s.isalpha()`` Boolean if alphabetic 377 | ``s.isdecimal()`` Boolean if decimal 378 | ``s.isdigit()`` Boolean if digit 379 | ``s.isidentifier()`` Boolean if valid identifier 380 | ``s.islower()`` Boolean if lowercase 381 | ``s.isnumeric()`` Boolean if numeric 382 | ``s.isprintable()`` Boolean if printable 383 | ``s.isspace()`` Boolean if whitespace 384 | ``s.istitle()`` Boolean if titlecased 385 | ``s.isupper()`` Boolean if uppercased 386 | ``s.join(iterable)`` Return a string inserted between sequence 387 | ``s.ljust(w, [char])`` Left justify in ``w`` spaces with ``char`` (default ``' '``) 388 | ``s.lower()`` Lowercase 389 | ``s.lstrip([chars])`` Left strip ``chars`` (default spacing). 390 | ``s.partition(sub)`` Split string at first occurrence of substring, return ``(before, sub, after)`` 391 | ``s.removeprefix(sub)`` Remove ``sub`` from start of string 392 | ``s.removesuffix(sub)`` Remove ``sub`` from end of string 393 | ``s.replace(old, new, [count])`` Replace substring with new string 394 | ``s.rfind(sub, [start, [end]])`` Find rightmost substring or return ``-1`` 395 | ``s.rindex(sub, [start, [end]])`` Find rightmost substring or raise ``ValueError`` 396 | ``s.rjust(w, [char)`` Right justify in w spaces with char (default ``" "``) 397 | ``s.rpartition(sub)`` Rightmost partition 398 | ``s.rsplit([sep, [maxsplit=-1])`` Rightmost split by ``sep`` (defaults to whitespace) 399 | ``s.rstrip([chars])`` Right strip 400 | ``s.split([sep, [maxsplit=-1]])`` Split a string into sequence around substring 401 | ``s.splitlines( keepends=False)`` Break string at line boundaries 402 | ``s.startswith( prefix, [start, [end]])`` Check for prefix 403 | ``s.strip([chars])`` Remove leading and trailing whitespace (default) or ``chars`` 404 | ``s.swapcase()`` Swap casing of string 405 | ``s.title()`` Titlecase string 406 | ``s.translate(table)`` Use a translation table to replace strings 407 | ``s.upper()`` Uppercase 408 | ``s.zfill(width)`` Left fill with ``0`` so string fills ``width`` (no truncation) 409 | ======================================================= =========================================================== 410 | 411 | 412 | Lists 413 | ----- 414 | 415 | Lists are ordered mutable sequences. They can be created with the list literal syntax:: 416 | 417 | >>> people = ['Paul', 'John', 'George'] 418 | >>> people.append('Ringo') 419 | 420 | Lists can also be created by calling the constructor with an optional sequence:: 421 | 422 | 423 | >>> people = list(('Paul', 'John', 'George')) 424 | >>> people 425 | ['Paul', 'John', 'George'] 426 | 427 | The ``in`` operator is useful for checking membership on sequences:: 428 | 429 | >>> 'Yoko' in people 430 | False 431 | 432 | If we need the index number during iteration, the ``enumerate`` function gives us a tuple of index, item pairs:: 433 | 434 | >>> for i, name in enumerate(people, 1): 435 | ... print('{} - {}'.format(i, name)) 436 | 1 - Paul 437 | 2 - John 438 | 3 - George 439 | 440 | 441 | We can do index operations on most sequences:: 442 | 443 | >>> people[0] 444 | 'Paul' 445 | >>> people[-1] # len(people) - 1 446 | 'George' 447 | 448 | We can also do *slicing* operations on most sequences:: 449 | 450 | >>> people[1:2] 451 | ['John'] 452 | >>> people[:1] # Implicit start at 0 453 | ['Paul'] 454 | >>> people[1:] # Implicit end at len(people) 455 | ['John', 'George'] 456 | >>> people[::2] # Take every other item 457 | ['Paul', 'George'] 458 | >>> people[::-1] # Reverse sequence 459 | ['George', 'John', 'Paul'] 460 | 461 | 462 | .. raw:: latex 463 | 464 | \Needspace{5\baselineskip} 465 | 466 | 467 | .. longtable: format: {p{.25\textwidth} l >{\raggedright\arraybackslash}p{.35\textwidth}} 468 | 469 | .. longtable: format: {>{\hangindent=1em\hangafter=1 }p{.25\textwidth} l >{\hangindent=1em\hangafter=1 }p{.35\textwidth}} 470 | 471 | .. table:: List Operations 472 | 473 | ================================== ========================= ============================================================ 474 | Operation Provided By Result 475 | ================================== ========================= ============================================================ 476 | ``l + l2`` ``__add__`` List concatenation (see ``.extend``) 477 | ``"name" in l`` ``__contains__`` Membership 478 | ``del l[idx]`` ``__del__`` Remove item at index ``idx`` (see ``.pop``) 479 | ``l == l2`` ``__eq__`` Equality 480 | ``"{}".format(l)`` ``__format__`` String format of list 481 | ``l >= l2`` ``__ge__`` Greater or equal. Compares items in lists from left 482 | ``l[idx]`` ``__getitem__`` Index operation 483 | ``l > l2`` ``__gt__`` Greater. Compares items in lists from left 484 | No hash ``__hash__`` Set to ``None`` to ensure you can't insert in dictionary 485 | ``l += l2`` ``__iadd__`` Augmented (mutates ``l``) concatenation 486 | ``l *= 3`` ``__imul__`` Augmented (mutates ``l``) repetition 487 | ``for thing in l:`` ``__iter__`` Iteration 488 | ``l <= l2`` ``__le__`` Less than or equal. Compares items in lists from left 489 | ``len(l)`` ``__len__`` Length 490 | ``l < l2`` ``__lt__`` Less than. Compares items in lists from left 491 | ``l * 2`` ``__mul__`` Repetition 492 | ``l != l2`` ``__ne__`` Not equal 493 | ``repr(l)`` ``__repr__`` Programmer friendly string 494 | ``reversed(l)`` ``__reversed__`` Reverse 495 | ``foo * l`` ``__rmul__`` Called if ``foo`` doesn't implement ``__mul__`` 496 | ``l[idx] = 'bar'`` ``__setitem__`` Index operation to set value 497 | ``l.__sizeof__()`` ``__sizeof__`` Bytes for internal representation 498 | ``str(l)`` ``__str__`` User friendly string 499 | ================================== ========================= ============================================================ 500 | 501 | .. longtable: format: {p{.4\textwidth} p{.55\textwidth}} 502 | 503 | .. longtable: format: {>{\hangindent=1em\hangafter=1 }p{.4\textwidth} >{\hangindent=1em\hangafter=1 }p{.55\textwidth}} 504 | 505 | .. table:: List Methods 506 | 507 | ============================================================ ============================================================ 508 | Operation Result 509 | ============================================================ ============================================================ 510 | ``l.append(item)`` Append ``item`` to end 511 | ``l.clear()`` Empty list (mutates ``l``) 512 | ``l.copy()`` Shallow copy 513 | ``l.count(thing)`` Number of occurrences of ``thing`` 514 | ``l.extend(l2)`` List concatenation (mutates ``l``) 515 | ``l.index(thing[, start[, stop]])`` Index of ``thing`` else ``ValueError``. Python 3.10 has added optional arguments start and stop to search for ``thing`` within a subsection of the array 516 | ``l.insert(idx, bar)`` Insert ``bar`` at index ``idx`` 517 | ``l.pop([idx])`` Remove last item or item at ``idx`` 518 | ``l.remove(bar)`` Remove first instance of ``bar`` else ``ValueError`` 519 | ``l.reverse()`` Reverse (mutates ``l``) 520 | ``l.sort([key=], reverse=False)`` In-place sort, by optional ``key`` function (mutates ``l``) 521 | ============================================================ ============================================================ 522 | 523 | 524 | 525 | Dictionaries 526 | -------------- 527 | 528 | Dictionaries are mutable mappings of keys to values. Keys 529 | must be hashable, but values can be any object. Here is a dictionary 530 | literal:: 531 | 532 | >>> instruments = {'Paul': 'Bass', 533 | ... 'John': 'Guitar'} 534 | 535 | Dictionaries can also be made by calling the constructor with an optional 536 | mapping, an iterable, or using keyword arguments. The iterable must be a sequence of 2-pairs:: 537 | 538 | >>> instruments = dict([('Paul', 'Bass'), 539 | ... ('John', 'Guitar')]) 540 | 541 | Here is an example using keyword arguments:: 542 | 543 | >>> instruments = dict(Paul='Bass', 544 | ... John='Guitar') 545 | 546 | 547 | If you have two parallel arrays the following also works:: 548 | 549 | >>> names = ['Paul', 'John'] 550 | >>> insts = ['Bass', 'Guitar'] 551 | >>> instruments = dict(zip(names, insts)) 552 | 553 | They support index operations, containment, and looping:: 554 | 555 | >>> instruments['George'] = 'Guitar' 556 | >>> 'Ringo' in instruments 557 | False 558 | 559 | >>> for name in instruments: 560 | ... print('{} - {}'.format(name, 561 | ... instruments[name])) 562 | Paul - Bass 563 | John - Guitar 564 | George - Guitar 565 | 566 | Dictionaries have an ``.update`` method to merge two dictionaries:: 567 | 568 | >>> i2 = {'Ringo': 'Drums'} 569 | >>> i2.update(instruments) 570 | >>> i2 571 | {'Ringo': 'Drums', 'Paul': 'Bass', 'John': 'Guitar', 572 | 'George': 'Guitar'} 573 | 574 | PEP 448 introduced Additional Unpacking Generalizations in Python 3.5. This adds the ability to unpack into a dictionary literal and can be used to merge dictionaries:: 575 | 576 | >>> {'Ringo': 'Drums', **instruments} 577 | {'Ringo': 'Drums', 'Paul': 'Bass', 'John': 'Guitar', 578 | 'George': 'Guitar'} 579 | 580 | You can unpack into the ``dict`` constructor if the keys are strings:: 581 | 582 | >>> dict(Ringo='Drums', **instruments) 583 | {'Ringo': 'Drums', 'Paul': 'Bass', 'John': 'Guitar', 584 | 'George': 'Guitar'} 585 | 586 | PEP 584 added union operators to dictionaries (Python 3.9):: 587 | 588 | >>> {'Ringo': 'Drums'} | instruments 589 | {'Ringo': 'Drums', 'Paul': 'Bass', 'John': 'Guitar', 590 | 'George': 'Guitar'} 591 | 592 | 593 | .. longtable: format: {p{.25\textwidth} l >{\raggedright\arraybackslash}p{.35\textwidth}} 594 | 595 | 596 | .. longtable: format: {>{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.25\textwidth} l >{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.35\textwidth}} 597 | 598 | .. table:: Magic Dictionary Methods 599 | 600 | ======================================= ========================= ============================================================ 601 | Operation Provided By Result 602 | ======================================= ========================= ============================================================ 603 | ``key in d`` ``__contains__`` Membership 604 | ``del d[key]`` ``__delitem__`` Delete key 605 | ``d == d2`` ``__eq__`` Equality. Dicts are equal or not equal 606 | ``"{}".format(d)`` ``__format__`` String format of dict 607 | ``d[key]`` ``__getitem__`` Get value for ``key`` (see ``.get``) 608 | ``for key in d:`` ``__iter__`` Iteration over keys 609 | ``len(d)`` ``__len__`` Length 610 | ``d != d2`` ``__ne__`` Not equal 611 | ``repr(d)`` ``__repr__`` Programmer friendly string 612 | ``d[key] = value`` ``__setitem__`` Set ``value`` for ``key`` 613 | ``d.__sizeof__()`` ``__sizeof__`` Bytes for internal representation 614 | ``d | d2`` ``__or__`` Return a new dictionary overwriting common keys with ``d2`` 615 | ``d |= d2`` ``__ior__`` Mutate ``d`` with values of ``d2`` (dictionary or iterable of (key, value) pairs) 616 | ======================================= ========================= ============================================================ 617 | 618 | 619 | .. longtable: format: {p{.3\textwidth} >{\raggedright\arraybackslash}p{.6\textwidth}} 620 | 621 | .. longtable: format: {>{\hangindent=1em\hangafter=1 }p{.3\textwidth} >{\hangindent=1em\hangafter=1 }p{.6\textwidth}} 622 | 623 | .. table:: Dictionary Methods 624 | 625 | 626 | ================================================================= ============================================================ 627 | Operation Result 628 | ================================================================= ============================================================ 629 | ``d.clear()`` Remove all items (mutates ``d``) 630 | ``d.copy()`` Shallow copy 631 | ``d.fromkeys(iter, value=None)`` Create dict from iterable with values set to value 632 | ``d.get(key, [default])`` Get value for ``key`` or return default (``None``) 633 | ``d.items()`` View of (key, value) pairs 634 | ``d.keys()`` View of keys 635 | ``d.pop(key, [default])`` Return value for key or default (``KeyError`` if not set) 636 | ``d.popitem()`` Return arbitrary (key, value) tuple. ``KeyError`` if empty 637 | ``d.setdefault(k, [default])`` Does ``d.get(k, default)``. If ``k`` missing, sets to default 638 | ``d.update(d2)`` Mutate ``d`` with values of ``d2`` (dictionary or iterable of (key, value) pairs) 639 | ``d.values()`` View of values 640 | ================================================================= ============================================================ 641 | 642 | 643 | Tuples 644 | ------- 645 | 646 | Tuples are immutable sequences. Typically they are used to store 647 | *record* type data. Here they are created with tuple literals:: 648 | 649 | >>> member = ('Paul', 'Bass', 1942) 650 | >>> member2 = ('Ringo', 'Drums', 1940) 651 | 652 | You can also use the tuple constructor which takes an optional sequence:: 653 | 654 | >>> member2 = tuple(['Ringo', 'Drums', 1940]) 655 | 656 | Note that parentheses aren't usually required:: 657 | 658 | >>> row = 1, 'Fred' # 2 item tuple 659 | >>> row2 = (2, 'Bob') # 2 item tuple 660 | >>> row3 = ('Bill') # String! 661 | >>> row4 = ('Bill',) # 1 item tuple 662 | >>> row5 = 'Bill', # 1 item tuple 663 | >>> row6 = () # Empty tuple 664 | 665 | Named tuples can be used in place of normal tuples and allow context (or names) 666 | to be added to positional members. The syntax for creating them is a little 667 | different because we are dynamically creating a class first (hence the 668 | capitalized variable):: 669 | 670 | >>> from collections import namedtuple 671 | >>> Member = namedtuple('Member', 672 | ... 'name, instrument, birth_year') 673 | >>> member3 = Member('George', 'Guitar', 1943) 674 | 675 | We can access members by position or name (name allows us to be more explicit):: 676 | 677 | >>> member3[0] 678 | 'George' 679 | 680 | >>> member3.name 681 | 'George' 682 | 683 | .. longtable: format: {p{.3\textwidth} l >{\raggedright\arraybackslash}p{.3\textwidth}} 684 | 685 | .. longtable: format: {>{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.3\textwidth} l >{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.3\textwidth}} 686 | 687 | .. table:: Tuple Operations 688 | 689 | ================================== ========================= ============================================================ 690 | Operation Provided Result 691 | ================================== ========================= ============================================================ 692 | ``t + t2`` ``__add__`` Tuple concatenation 693 | ``"name" in t`` ``__contains__`` Membership 694 | ``t == t2`` ``__eq__`` Equality 695 | ``"{}".format(t)`` ``__format__`` String format of tuple 696 | ``t >= t2`` ``__ge__`` Greater or equal. Compares items in tuple from left 697 | ``t[idx]`` ``__getitem__`` Index operation 698 | ``t > t2`` ``__gt__`` Greater. Compares items in tuple from left 699 | ``hash(t)`` ``__hash__`` For set/dict insertion 700 | ``for thing in t:`` ``__iter__`` Iteration 701 | ``t <= t2`` ``__le__`` Less than or equal. Compares items in tuple from left 702 | ``len(t)`` ``__len__`` Length 703 | ``t < t2`` ``__lt__`` Less than. Compares items in tuple from left 704 | ``t * 2`` ``__mul__`` Repetition 705 | ``t != t2`` ``__ne__`` Not equal 706 | ``repr(t)`` ``__repr__`` Programmer friendly string 707 | ``foo * t`` ``__rmul__`` Called if ``foo`` doesn't implement ``__mul__`` 708 | ``t.__sizeof__()`` ``__sizeof__`` Bytes for internal representation 709 | ``str(t)`` ``__str__`` User friendly string 710 | ================================== ========================= ============================================================ 711 | 712 | 713 | .. longtable: format: {p{.3\textwidth} p{.6\textwidth}} 714 | 715 | .. table:: Tuple Methods 716 | 717 | ============================================================ ============================================================ 718 | Operation Result 719 | ============================================================ ============================================================ 720 | ``t.count(item)`` Count of item 721 | ``t.index(thing)`` Index of ``thing`` else ``ValueError`` 722 | ============================================================ ============================================================ 723 | 724 | Sets 725 | ----- 726 | 727 | A set is a mutable unordered collection that cannot contain duplicates. 728 | Sets can be created with the literal syntax:: 729 | 730 | >>> vowels = {'a', 'e', 'i', 'o', 'u'} 731 | 732 | Set can also be created by passing a sequence to the constructor:: 733 | 734 | >>> vowels = set('aeiou') 735 | 736 | 737 | Sets are used to 738 | remove duplicates and test for membership:: 739 | 740 | >>> digits = [0, 1, 1, 2, 3, 4, 5, 6, 741 | ... 7, 8, 9] 742 | >>> digit_set = set(digits) # remove extra 1 743 | 744 | >>> 9 in digit_set 745 | True 746 | 747 | Sets are useful because they provide *set operations*, such as union 748 | (``|``), intersection (``&``), difference (``-``), and xor (``^``):: 749 | 750 | >>> odd = {1, 3, 5, 7, 9} 751 | >>> prime = set([2, 3, 5, 7]) 752 | >>> even = digit_set - odd 753 | >>> even 754 | {0, 2, 4, 6, 8} 755 | 756 | >>> prime & even # in intersection 757 | {2} 758 | 759 | >>> odd | even # in both 760 | {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 761 | 762 | >>> even ^ prime # not in both 763 | {0, 3, 4, 5, 6, 7, 8} 764 | 765 | .. raw:: latex 766 | 767 | \Needspace{10\baselineskip} 768 | 769 | 770 | .. note:: 771 | 772 | There is no literal syntax for an empty set. You need to use:: 773 | 774 | >>> empty = set() 775 | 776 | 777 | 778 | .. longtable: format: {p{.25\textwidth} l >{\raggedright\arraybackslash}p{.35\textwidth}} 779 | 780 | .. longtable: format: {>{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.25\textwidth} l >{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.35\textwidth}} 781 | 782 | .. table:: Set Operations 783 | 784 | ======================================= ========================= ============================================================ 785 | Operation Provided By Result 786 | ======================================= ========================= ============================================================ 787 | ``s & s2`` ``__and__`` Set intersection (see ``.intersection``) 788 | ``"name" in s`` ``__contains__`` Membership 789 | ``s == s2`` ``__eq__`` Equality. Sets are equal or not equal 790 | ``"{}".format(s)`` ``__format__`` String format of set 791 | ``s >= s2`` ``__ge__`` ``s`` in ``s2`` (see ``.issuperset``) 792 | ``s > s2`` ``__gt__`` Strict superset (``s >= s2`` but ``s != s2``) 793 | No hash ``__hash__`` Set to ``None`` to ensure you can't insert in dictionary 794 | ``s &= s2`` ``__iand__`` Augmented (mutates ``s``) intersection (see ``.intersection _update``) 795 | ``s |= s2`` ``__ior__`` Augmented (mutates ``s``) union (see ``.update``) 796 | ``s -= s2`` ``__isub__`` Augmented (mutates ``s``) difference (see ``.difference_update``) 797 | ``for thing in s:`` ``__iter__`` Iteration 798 | ``s ^= s2`` ``__ixor__`` Augmented (mutates ``s`` ) xor (see ``.symmetric _difference_update``) 799 | ``s <= s2`` ``__le__`` ``s2`` in ``s`` (see ``.issubset``) 800 | ``len(s)`` ``__len__`` Length 801 | ``s < s2`` ``__lt__`` Strict subset (``s <= s2`` but ``s != s2``) 802 | ``s != s2`` ``__ne__`` Not equal 803 | ``s | s2`` ``__or__`` Set union (see ``.union``) 804 | ``foo & s`` ``__rand__`` Called if ``foo`` doesn't implement ``__and__`` 805 | ``repr(s)`` ``__repr__`` Programmer friendly string 806 | ``foo | s`` ``__ror__`` Called if ``foo`` doesn't implement ``__or__`` 807 | ``foo - s`` ``__rsub__`` Called if ``foo`` doesn't implement ``__sub__`` 808 | ``foo ^ s`` ``__rxor__`` Called if ``foo`` doesn't implement ``__xor__`` 809 | ``s.__sizeof__()`` ``__sizeof__`` Bytes for internal representation 810 | ``str(s)`` ``__str__`` User friendly string 811 | ``s - s2`` ``__sub__`` Set difference (see ``.difference``) 812 | ``s ^ s2`` ``__xor__`` Set xor (see ``.symmetric _difference``) 813 | ======================================= ========================= ============================================================ 814 | 815 | .. raw:: latex 816 | 817 | %\Needspace{5\baselineskip} 818 | \clearpage 819 | 820 | 821 | 822 | .. longtable: format: {p{.55\textwidth} p{.35\textwidth}} 823 | 824 | .. longtable: format: {>{\hangindent=1em\hangafter=1\arraybackslash }p{.6\textwidth} >{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.30\textwidth}} 825 | 826 | .. table:: Set Methods 827 | 828 | ================================================================= ============================================================ 829 | Operation Result 830 | ================================================================= ============================================================ 831 | ``s.add(item)`` Add ``item`` to ``s`` (mutates ``s``) 832 | ``s.clear()`` Remove elements from ``s`` (mutates ``s``) 833 | ``s.copy()`` Shallow copy 834 | ``s.difference(s2)`` Return set with elements from ``s`` and not ``s2`` 835 | ``s.difference_update(s2)`` Remove ``s2`` items from ``s`` (mutates ``s``) 836 | ``s.discard(item)`` Remove ``item`` from s (mutates ``s``). No error on missing ``item`` 837 | ``s.intersection(s2)`` Return set with elements from both sets 838 | ``s.intersection_update(s2)`` Update ``s`` with members of ``s2`` (mutates ``s``) 839 | ``s.isdisjoint(s2)`` ``True`` if there is no intersection of these two sets 840 | ``s.issubset(s2)`` ``True`` if all elements of ``s`` are in ``s2`` 841 | ``s.issuperset(s2)`` ``True`` if all elements of ``s2`` are in ``s2`` 842 | ``s.pop()`` Remove arbitrary item from s (mutates ``s``). ``KeyError`` on missing ``item`` 843 | ``s.remove(item)`` Remove ``item`` from s (mutates ``s``). ``KeyError`` on missing ``item`` 844 | ``s.symmetric_difference(s2)`` Return set with elements only in one of the sets 845 | ``s.symmetric_difference_update(s2)`` Update ``s`` with elements only in one of the sets (mutates ``s``) 846 | ``s.union(s2)`` Return all elements of both sets 847 | ``s.update(s2)`` Update ``s`` with all elements of both sets (mutates ``s``) 848 | ================================================================= ============================================================ 849 | 850 | Built in Functions 851 | ===================== 852 | 853 | In the default namespace you have access to various callables: 854 | 855 | .. longtable: format: {p{.35\textwidth} p{.55\textwidth}} 856 | 857 | .. longtable: format: {>{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.35\textwidth} >{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.55\textwidth}} 858 | 859 | .. table:: Built in callables 860 | 861 | ================================================================= ============================================================ 862 | Operation Result 863 | ================================================================= ============================================================ 864 | ``abs(x)`` Absolute value protocol (call ``x.__abs__()``) 865 | ``all(seq)`` Boolean check if all items in ``seq`` are truthy 866 | ``any(seq)`` Boolean check if at least one item in ``seq`` is truthy 867 | ``ascii(x)`` ASCII representation of object 868 | ``bin(i)`` String containing binary version of number (``int(bin(i), 2)`` to reverse) 869 | ``bool(x)`` Boolean protocol (call ``x.__bool__()``) 870 | ``breakpoint()`` Create a breakpoint (convenience to call ``sys.breakpointhook()`` ie ``import pdb; pdb.set_trace()``) 871 | ``bytearray(x)`` Create a mutable bytearray from iterable of ints, text string, bytes, an integer, or pass nothing for an empty bytearray 872 | ``bytes(x)`` Create an immutable bytes from iterable of ints, text string, bytes, an integer, or pass nothing for an empty bytes 873 | ``callable(x)`` Boolean check if you can do ``x()`` (ie ``x.__call__`` exists) 874 | ``chr(i)`` Convert integer codepoint to Unicode string (``ord(chr(i))`` to reverse) 875 | ``@classmethod`` Use to decorate a method so you can invoke it on the class 876 | ``compile(source, fname, mode)`` Compile ``source`` to code (``fname`` used for error, ``mode`` is ``exec``: module, ``single``: statement, ``eval``: expression). Can run ``eval(code)`` on expression, ``exec(code)`` on statement 877 | ``complex(i, y)`` Create complex number 878 | ``copyright`` Python copyright string 879 | ``credits`` Python credits string 880 | ``delattr(obj, attr)`` Remove attribute from ``obj`` (``del obj.attr``) 881 | ``dict([x])`` Create a dictionary from a mapping, iterable of k,v tuples, named parameters, or pass nothing for an empty dictionary 882 | ``dir([obj])`` List attributes of ``obj``, or names in current namespace if no ``obj`` provided (see ``vars``) 883 | ``divmod(num, denom)`` Return tuple pair of ``num//denom`` and ``num%denom`` 884 | ``enumerate(seq, [start])`` Return iterator of index, item tuple pairs. Index begins at ``start`` or ``0`` (default) 885 | ``eval(source, globals=None, locals=None)`` Run ``source`` (expression string or result of ``compile``) with globals and locals 886 | ``exec(source, globals=None, locals=None)`` Run ``source`` (statement string or result of ``compile``) with globals and locals 887 | ``exit([code])`` Exit Python interpreter and return code (default 0) 888 | ``filter([function], seq)`` Return iterator of items where ``function(item)`` is truthy (or ``item`` is truthy if ``function`` is missing) 889 | ``float(x)`` Convert string or number to float (call ``x.__float__()``) 890 | ``format(obj, fmt)`` Format protocol (call ``obj.__format__(fmt)``) 891 | ``frozenset([seq])`` Create ``frozenset`` from ``seq`` (empty if missing) 892 | ``getattr(obj, attr)`` Get attribute from ``obj`` (``obj.attr``) 893 | ``globals()`` Return *mutable* dictionary with current global variables 894 | ``hasattr(obj, attr)`` Check if attribute on ``obj`` (``obj.attr`` doesn't throw ``AttributeError``) 895 | ``hash(x)`` Hash value protocol for object (call ``x.__hash__()``) 896 | ``help([x])`` Start interactive help (if no ``x``), or print documentation for ``x`` 897 | ``hex(i)`` String containing hexadecimal version of number (``int(hex(i), 16)`` to reverse) 898 | ``id(x)`` Identity of ``x`` 899 | ``input([prompt])`` Read string from standard input 900 | ``int(x, [base=10])`` Create integer from number or string 901 | ``isinstance(obj, class_or_tuple)`` Boolean check if ``obj`` is an instance or subclass of ``class_or_tuple``. As of PEP 604 (Python 3.10), calls to this method is also supported with a type union object. 902 | ``issubclass(cls, class_or_tuple)`` Boolean check if ``cls`` is the class or derived from ``class_or_tuple``. As of PEP 604 (Python 3.10), calls to this method is also supported with a type union object. 903 | ``iter(seq)`` Iteration protocol (call ``seq.__iter__()``) 904 | ``len(seq)`` Number of items in sequence 905 | ``license()`` Display Python licenses 906 | ``list([seq])`` Convert ``seq`` to list (empty if missing) 907 | ``locals()`` Return dictionary of local attributes (unlike ``globals``, not guaranteed to update namespace when mutated) 908 | ``map(function, *seqs)`` Call ``function(item)`` for item in ``seqs`` (if single sequence) or ``function(seqs[0][0], seqs[1][0]...)`` 909 | ``max(seq, *, [default], [key])`` Return maximum value from ``seq``. ``default`` (value if empty ``seq``) and ``key`` (function to determine magnitude) are keyword parameters. 910 | ``memoryview(obj)`` Create ``memoryview`` from ``obj`` 911 | ``min(seq, *, [default], [key])`` Return minimum value from ``seq``. ``default`` (value if empty ``seq``) and ``key`` (function to determine magnitude) are keyword parameters. 912 | ``next(iter, [default])`` Get next item from iteration protocol (call ``iter.__next__()``), if ``default`` provide return instead of raising ``StopIteration`` 913 | ``object`` Root base type 914 | ``oct(i)`` String containing octal version of number (``int(oct(i), 8)`` to reverse) 915 | ``open(filename, [mode], [encoding], [errors])`` Open a file 916 | ``ord(s)`` Convert Unicode string to integer codepoint (``chr(ord(s))`` to reverse) 917 | ``pow(num, exp, [z])`` Power protocol (call ``num.__pow__(exp, z)``) (``num ** exp`` or ``num ** exp % z``) 918 | ``print(val, [val2 ...], *, sep=' ', end='\n', file=sys.stdout)`` Print values to ``file``. Print protocol (call ``val.__str__()``) 919 | ``@property`` Decorator to turn a method into an attribute 920 | ``quit()`` Quit interpreter 921 | ``range([start], stop, [step])`` Return range object that iterates from ``start`` (default ``0``) to ``stop - 1``, by ``step`` increments (default ``1``) 922 | ``repr(x)`` Representation protocol (call ``x.__repr__()``) 923 | ``reversed(seq)`` Reverse iterator 924 | ``round(num, [ndigits=0])`` Round to ``ndigits`` protocol (call ``num.__round__()``) (use banker's rounding) 925 | ``set([seq])`` Create ``set`` from ``seq`` (empty if missing) 926 | ``setattr(obj, attr, val)`` Set attribute on ``obj`` (``obj.attr = val``) 927 | ``slice([start], stop, [step])`` Create ``slice`` object 928 | ``sorted(seq, * [key=None], [reverse=False])`` Sorted list in ascending order (use ``key`` function to customize sort property) 929 | ``@staticmethod`` Use to decorate a method so you can invoke it on the class or instance 930 | ``str(obj)`` Create string (call ``obj.__str__()``) 931 | ``str(bytes, [encoding], [errors])`` Create string from bytes (``errors`` defaults to ``strict``) 932 | ``sum(seq, [start=0])`` Sum values from ``seq`` (use ``start`` as initial value) 933 | ``super()`` Get access to superclass 934 | ``tuple([seq])`` Convert ``seq`` to tuple (empty if missing) 935 | ``type(name, bases, dict)`` Create a new type of ``name``, with base classes ``bases``, and attributes ``dict`` 936 | ``type(obj)`` Return type of ``obj`` 937 | ``vars([obj])`` Return ``obj.__dict__`` or ``locals()`` if missing (see ``dir``) 938 | ``zip(seq1, [seq2, ...], [strict=False])`` Return iterable of tuples of ``(seq1[0], seq2[0])``, ``(seq1[1], seq2[1])``, ... until shortest sequence (set ``strict=True`` to require all sequences have an equal length) 939 | ================================================================= ============================================================ 940 | 941 | Unicode 942 | ========= 943 | 944 | Python 3 represents strings as Unicode. We can *encode* strings to a series of 945 | bytes such as UTF-8. If we have bytes, we can *decode* them to a Unicode string:: 946 | 947 | >>> x_sq = 'x²' 948 | >>> x_sq.encode('utf-8') 949 | b'x\xc2\xb2' 950 | 951 | >>> utf8_bytes = b'x\xc2\xb2' 952 | >>> utf8_bytes.decode('utf-8') 953 | 'x²' 954 | 955 | If you have the unicode glyph, you can use that directly. Alternatively, you 956 | can enter a code point using ``\u`` followed by the 16-bit hex value xxxx. 957 | For larger code points, use ``\U`` followed by xxxxxxxx. If you have the 958 | Unicode name (obtained by consulting tables at unicode.org), you can use 959 | the ``\N`` syntax. The following are equivalent:: 960 | 961 | >>> result = 'x²' 962 | >>> result = 'x\u00b2' 963 | >>> result = 'x\N{SUPERSCRIPT TWO}' 964 | 965 | .. figure:: img/py/uniencode.png 966 | 967 | Image illustrating *encoding* a Unicode string to a byte representation. In this case, 968 | we convert to UTF-8. There are other byte encodings for this string. If we have a UTF-8 969 | byte string, we can *decode* it into a Unicode string. Note that we should be explicit 970 | about the decoding as there are potentially other encodings that we could decode to 971 | that might give the user erroneous data, or *mojibake*. 972 | 973 | .. note:: 974 | 975 | PEP 3131 introduced Unicode identifiers. You can 976 | create variables that have Unicode characters in them:: 977 | 978 | >>> Ω_val = 10 979 | >>> Ω_val 980 | 10 981 | 982 | String Formatting 983 | ================= 984 | 985 | Most modern Python code uses the ``.format`` method (PEP 3101) to create strings from other parts. The format method uses ``{}`` as a placeholder. 986 | 987 | Inside of the placeholder we can provide different specifiers: 988 | 989 | * ``{0}`` - reference first positional argument 990 | * ``{}`` - reference implicit positional argument 991 | * ``{result}`` - reference keyword argument 992 | * ``{bike.tire}`` - reference attribute of argument 993 | * ``{names[0]}`` - reference first element of argument 994 | 995 | :: 996 | 997 | >>> person = {'name': 'Paul', 998 | ... 'instrument': 'Bass'} 999 | >>> inst = person['instrument'] 1000 | 1001 | 1002 | >>> print("Name: {} plays: {}".format( 1003 | ... person['name'], inst)) 1004 | Name: Paul plays: Bass 1005 | 1006 | or:: 1007 | 1008 | >>> print("Name: {name} " 1009 | ... "plays: {inst}".format( 1010 | ... name=person['name'], inst=inst)) 1011 | Name: Paul plays: Bass 1012 | 1013 | You can also use *f-strings* in Python 3.6 (see PEP 498):: 1014 | 1015 | >>> print(f'Name: {person["name"]} plays: {inst}') 1016 | Name: Paul plays: Bass 1017 | 1018 | F-strings inspect variables that are available and allow you to 1019 | inline methods, or attributes from those variables. 1020 | 1021 | In Python 3.8, f-strings support ``=`` for self-documenting 1022 | expressions, which insert the variable name before the value. 1023 | This is useful for debugging:: 1024 | 1025 | >>> name = 'Paul' 1026 | >>> print(f'{name=}') 1027 | name='Paul' 1028 | 1029 | You can also use the ``=`` specifier with expressions:: 1030 | 1031 | >>> print(f'Name: {person["name"]=} plays: {inst=}') 1032 | Name: person["name"]='Paul' plays: inst='Bass' 1033 | 1034 | 1035 | Conversion Flags 1036 | ---------------- 1037 | 1038 | You can provide a *conversion flag* inside the placeholder. 1039 | 1040 | * ``!s`` - Call ``str()`` on argument 1041 | * ``!r`` - Call ``repr()`` on argument 1042 | * ``!a`` - Call ``ascii()`` on argument 1043 | 1044 | :: 1045 | 1046 | >>> class Cat: 1047 | ... def __init__(self, name): 1048 | ... self.name = name 1049 | ... def __format__(self, data): 1050 | ... return "Format" 1051 | ... def __str__(self): 1052 | ... return "Str" 1053 | ... def __repr__(self): 1054 | ... return "Repr" 1055 | 1056 | >>> cat = Cat("Fred") 1057 | >>> print("{} {!s} {!a} {!r}".format(cat, cat, cat, 1058 | ... cat)) 1059 | Format Str Repr Repr 1060 | 1061 | Format Specification 1062 | -------------------- 1063 | 1064 | You can provide a format specification following a colon. The grammar for format specification is as follows:: 1065 | 1066 | [[fill]align][sign][#][0][width][grouping_option] 1067 | [.precision][type] 1068 | 1069 | The following table lists the field meanings. 1070 | 1071 | .. longtable: format: {>{\hangindent=1em\hangafter=1\raggedright\arraybackslash }r >{\hangindent=1em\hangafter=1\raggedright\arraybackslash}p{.55\textwidth}} 1072 | 1073 | 1074 | =================== ================================= 1075 | Field Meaning 1076 | =================== ================================= 1077 | fill Character used to fill in 1078 | ``align`` (default is space) 1079 | align Alight output ``<`` (left align), 1080 | ``>`` (right align), 1081 | ``^`` (center align), or 1082 | ``=`` (put padding after sign) 1083 | sign For numbers ``+`` (show sign 1084 | on both positive and negative 1085 | numbers, 1086 | ``-`` (default, only on negative), or 1087 | *space* (leading space for 1088 | positive, sign on negative) 1089 | # Prefix integers. ``0b`` (binary), 1090 | ``0o`` (octal), or ``0x`` (hex) 1091 | 0 Enable zero padding 1092 | width Minimum field width 1093 | grouping_option Number separator ``,`` (use comma for thousands 1094 | separator), ``_`` (Use underscore 1095 | for thousands separator) 1096 | .precision For floats (digits after period (floats), 1097 | for non-numerics (max length) 1098 | type Number type or ``s`` (string format default) 1099 | see Integer and Float charts 1100 | =================== ================================= 1101 | 1102 | The tables below lists the various options we have for formatting integer and floating point numbers. 1103 | 1104 | =================== ================================= 1105 | Integer Types Meaning 1106 | =================== ================================= 1107 | ``b`` binary 1108 | ``c`` character - convert to unicode 1109 | character 1110 | ``d`` decimal (default) 1111 | ``n`` decimal with locale specific 1112 | separators 1113 | ``o`` octal 1114 | ``x`` hex (lower-case) 1115 | ``X`` hex (upper-case) 1116 | =================== ================================= 1117 | 1118 | .. raw:: latex 1119 | 1120 | \Needspace{5\baselineskip} 1121 | 1122 | 1123 | 1124 | .. longtable: format: {>{\hangindent=1em\hangafter=1\raggedright\arraybackslash }r >{\hangindent=1em\hangafter=1\raggedright\arraybackslash}p{.55\textwidth}} 1125 | 1126 | =================== ================================= 1127 | Float Types Meaning 1128 | =================== ================================= 1129 | ``e``/``E`` Exponent. Lower/upper-case e 1130 | ``f`` Fixed point 1131 | ``g``/``G`` General. Fixed with exponent for 1132 | large, 1133 | and small numbers (``g`` default) 1134 | ``n`` ``g`` with locale specific 1135 | separators 1136 | ``%`` Percentage (multiplies by 100) 1137 | =================== ================================= 1138 | 1139 | Some ``format`` Examples 1140 | ------------------------ 1141 | 1142 | Here are a few examples of using ``.format``. 1143 | Let’s format a string in the center of 12 characters surrounded by ``*``. 1144 | ``*`` is the *fill* character, ``^`` is the *align* field, and ``12`` is the 1145 | *width* field:: 1146 | 1147 | >>> "Name: {:*^12}".format("Ringo") 1148 | 'Name: ***Ringo****' 1149 | 1150 | Next, we format a percentage using a width of 10, one decimal place and the 1151 | sign before the width padding. ``=`` is the *align* field, ``10.1`` are the *width* 1152 | and *precision* fields, and ``%`` is the *float type*, which converts the number 1153 | to a percentage:: 1154 | 1155 | >>> "Percent: {:=10.1%}".format(-44/100) 1156 | 'Percent: - 44.0%' 1157 | 1158 | Below is a binary and a hex conversion. The *integer type* field is set to ``b`` and ``x`` respectively:: 1159 | 1160 | >>> "Binary: {:#b}".format(12) 1161 | 'Binary: 0b1100' 1162 | 1163 | >>> "Hex: {:#x}".format(12) 1164 | 'Hex: 0xc' 1165 | 1166 | Files 1167 | ========== 1168 | 1169 | The ``open`` function will take a file path and mode as input and return a file 1170 | handle. There are various modes to open a file, depending on the content and 1171 | your needs. If you open the file in binary mode, you will get bytes out. In text 1172 | mode you will get strings back: 1173 | 1174 | .. longtable: format: {r l} 1175 | 1176 | .. table:: File Modes 1177 | 1178 | 1179 | ================= ====================================================================== 1180 | Mode Meaning 1181 | ================= ====================================================================== 1182 | ``'r'`` Read text file (default) 1183 | ``'w'`` Write text file (truncates if exists) 1184 | ``'x'`` Write text file, throw ``FileExistsError`` if exists. 1185 | ``'a'`` Append to text file (write to end) 1186 | ``'rb'`` Read binary file 1187 | ``'wb'`` Write binary (truncate) 1188 | ``'w+b'`` Open binary file for reading and writing 1189 | ``'xb'`` Write binary file, throw ``FileExistsError`` if exists. 1190 | ``'ab'`` Append to binary file (write to end) 1191 | ================= ====================================================================== 1192 | 1193 | Writing Files 1194 | -------------- 1195 | 1196 | We use a context manager with a file to ensure that the file is closed when the context block exits. 1197 | 1198 | :: 1199 | 1200 | >>> with open('/tmp/names.txt', 'w') as fout: 1201 | ... fout.write('Paul\r\nJohn\n') 1202 | ... fout.writelines(['Ringo\n', 'George\n']) 1203 | 1204 | Reading Files 1205 | ------------- 1206 | 1207 | With an opened text file, you can iterate over the lines. This saves memory as the lines are only read in as needed:: 1208 | 1209 | >>> with open('/tmp/names.txt') as fin: 1210 | ... for line in fin: 1211 | ... print(repr(line)) 1212 | 'Paul\n' 1213 | 'John\n' 1214 | 'Ringo\n' 1215 | 'George\n' 1216 | 1217 | .. longtable: format: {p{.25\textwidth} p{.65\textwidth}} 1218 | 1219 | .. longtable: format: {>{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.25\textwidth} >{\hangindent=1em\hangafter=1\raggedright\arraybackslash }p{.65\textwidth}} 1220 | 1221 | .. table:: File Methods/Attributes 1222 | 1223 | ================================================================= ============================================================ 1224 | Operation Result 1225 | ================================================================= ============================================================ 1226 | ``f.__iter__()`` Support iteration 1227 | ``f.__next__()`` Return next item of iteration (line in text) 1228 | ``f.__repr__()`` Implementation for ``repr(f)`` 1229 | ``f.buffer`` File buffer 1230 | ``f.close()`` Close file 1231 | ``f.closed`` Is closed 1232 | ``f.detach()`` Detach file buffer from file 1233 | ``f.encoding`` The encoding of the file (default is ``locale.getpreferredencoding()``) 1234 | ``f.errors`` Error mode of encoding (``'strict'`` default) 1235 | ``f.fileno()`` Return file descriptor 1236 | ``f.flush()`` Write file buffer 1237 | ``f.isatty()`` Is interactive file 1238 | ``f.linebuffering`` Buffered by lines 1239 | ``f.name`` Name of file 1240 | ``f.newlines`` End of line characters encountered (tuple or string) 1241 | ``f.read( size=-1)`` Read ``size`` characters (``-1`` is whole file) 1242 | ``f.readable()`` Is opened for reading 1243 | ``f.readline( size=-1)`` Read ``size`` characters from line (``-1`` is whole line) 1244 | ``f.readlines( hint=-1)`` Read bytes less than ``hint`` characters of lines from file (``-1`` is all file) 1245 | ``f.seek(cookie, whence=0)`` Change stream location to ``cookie`` bytes (may be negative) offset from ``whence`` (``0`` - start, ``1`` - current position, ``2`` - end). 1246 | ``f.seekable()`` File supports random access 1247 | ``f.tell()`` Current stream location 1248 | ``f.truncate( pos=None)`` Truncate file to ``pos`` bytes 1249 | ``f.writeable()`` File supports writing 1250 | ``f.write(text)`` Write ``text`` to file 1251 | ``f.writelines( lines)`` Write ``lines`` to file (provide newlines if you want them) 1252 | ================================================================= ============================================================ 1253 | 1254 | 1255 | Functions 1256 | ============ 1257 | 1258 | Defining functions 1259 | ------------------ 1260 | 1261 | Functions may take input, do some processing, and return output. You can 1262 | provide a docstring directly following the name 1263 | and parameters of the function:: 1264 | 1265 | 1266 | 1267 | >>> def add_numbers(x, y): 1268 | ... """ add_numbers sums up x and y 1269 | ... 1270 | ... Arguments: 1271 | ... x -- object that supports addition 1272 | ... y -- object that supports addition 1273 | ... """ 1274 | ... return x + y 1275 | 1276 | 1277 | .. note:: 1278 | 1279 | We use whitespace to specify a block in Python. We typically indent following a colon. PEP 8 recommends using 4 spaces. Don't mix tabs and spaces. 1280 | 1281 | We can create anonymous functions using the ``lambda`` statement. Because they 1282 | only allow an expression following the colon, it is somewhat crippled in functionality. 1283 | They are commonly used as a ``key`` argument to ``sorted``, ``min``, or ``max``:: 1284 | 1285 | >>> add = lambda x, y: x + y 1286 | >>> add(4, 5) 1287 | 9 1288 | 1289 | 1290 | Functions can have *default* arguments. Since Python 3.7, you can have more than 255 arguments for a single function! Be careful with mutable types as arguments, 1291 | as the default is bound to the function when the function is created, not when it is called:: 1292 | 1293 | >>> def add_n(x, n=42): 1294 | ... return x + n 1295 | 1296 | >>> add_n(10) 1297 | 52 1298 | >>> add_n(3, -10) 1299 | -7 1300 | 1301 | 1302 | 1303 | Functions can support variable positional arguments:: 1304 | 1305 | >>> def add_many(*args): 1306 | ... result = 0 1307 | ... for arg in args: 1308 | ... result += arg 1309 | ... return result 1310 | 1311 | >>> add_many() 1312 | 0 1313 | >>> add_many(1) 1314 | 1 1315 | >>> add_many(42, 3.14) 1316 | 45.14 1317 | 1318 | Functions can support variable keyword arguments:: 1319 | 1320 | >>> def add_kwargs(**kwargs): 1321 | ... result = 0 1322 | ... for key in kwargs: 1323 | ... result += kwargs[key] 1324 | ... return result 1325 | 1326 | >>> add_kwargs(x=1, y=2, z=3) 1327 | 6 1328 | 1329 | >>> add_kwargs() 1330 | 0 1331 | 1332 | >>> add_kwargs(4) 1333 | Traceback (most recent call last): 1334 | ... 1335 | TypeError: add_kwargs() takes 0 positional arguments 1336 | but 1 was given 1337 | 1338 | 1339 | You can indicate the end of positional parameters by using a single ``*``. This gives you *keyword only* parameters (PEP 3102):: 1340 | 1341 | >>> def add_points(*, x1=0, y1=0, x2=0, y2=0): 1342 | ... return x1 + x2, y1 + y2 1343 | 1344 | >>> add_points(x1=1, y1=1, x2=3, y2=4) 1345 | (4, 5) 1346 | 1347 | >>> add_points(1, 1, 3, 4) 1348 | Traceback (most recent call last): 1349 | ... 1350 | TypeError: add_points() takes 0 positional arguments 1351 | but 4 were given 1352 | 1353 | 1354 | Python 3.8 added *positional only* parameters (PEP 570). Parameters that precede a ``/`` are 1355 | positional only, and can have a keyword provided when they are invoked. 1356 | There are many Python functions coded in C (ie ``math.sin``) that do not support keyword 1357 | arguments, so this allows Python functions to emulate this behavior:: 1358 | 1359 | >>> def mysin(x, /): 1360 | ... import math 1361 | ... return math.sin(x) 1362 | 1363 | 1364 | .. note:: 1365 | 1366 | Many of the built-in functions and methods in Python have a ``/`` in 1367 | the documentation. That slash indicates that the parameters before it 1368 | are positional only:: 1369 | 1370 | >>> help(math.sin) 1371 | Help on built-in function sin in module math: 1372 | 1373 | sin(x, /) 1374 | Return the sine of x (measured in radians). 1375 | 1376 | 1377 | Calling Functions 1378 | ----------------- 1379 | 1380 | You can also use ``*`` and ``**`` to *unpack* sequence and dictionary 1381 | arguments:: 1382 | 1383 | >>> def add_all(*args, **kwargs): 1384 | ... """Add all arguments""" 1385 | ... result = 0 1386 | ... for num in args + tuple(kwargs.values()): 1387 | ... result += num 1388 | ... return result 1389 | 1390 | >>> sizes = (2, 4.5) 1391 | >>> named_sizes = {"this": 3, "that": 1} 1392 | 1393 | 1394 | 1395 | The following two examples are the equivalent:: 1396 | 1397 | >>> add_all(*sizes) 1398 | 6.5 1399 | 1400 | >>> add_all(sizes[0], sizes[1]) 1401 | 6.5 1402 | 1403 | 1404 | .. raw:: latex 1405 | 1406 | \Needspace{5\baselineskip} 1407 | 1408 | The following two examples are the equivalent:: 1409 | 1410 | 1411 | >>> add_all(**named_sizes) 1412 | 4 1413 | 1414 | >>> add_all(this=3, that=1) 1415 | 4 1416 | 1417 | You can also combine ``*`` and ``**`` on invocation:: 1418 | 1419 | 1420 | >>> add_all(*sizes, **named_sizes) 1421 | 10.5 1422 | 1423 | Getting Help 1424 | ------------ 1425 | 1426 | You can get help on a function that has a docstring by using ``help``:: 1427 | 1428 | >>> help(add_all) 1429 | Help on function add_all in module __main__: 1430 | 1431 | add_all(*args, **kwargs) 1432 | Add all arguments 1433 | 1434 | Classes 1435 | ========== 1436 | 1437 | Python supports object oriented programming but doesn't require you to create classes. You 1438 | can use the built-in data structures to great effect. Here's a class for a simple bike. The class attribute, 1439 | ``num_passengers``, is shared for all instances of ``Bike``. The instance attributes, ``size`` and 1440 | ``ratio``, are unique to each instance:: 1441 | 1442 | 1443 | >>> class Bike: 1444 | ... ''' Represents a bike ''' 1445 | ... num_passengers = 1 # class attribute 1446 | ... 1447 | ... def __init__(self, wheel_size, 1448 | ... gear_ratio): 1449 | ... ''' Create a bike specifying the 1450 | ... wheel size, and gear ratio ''' 1451 | ... # instance attributes 1452 | ... self.size = wheel_size 1453 | ... self.ratio = gear_ratio 1454 | ... 1455 | ... def gear_inches(self): 1456 | ... return self.ratio * self.size 1457 | 1458 | 1459 | 1460 | We can call the constructor (``__init__``), by invoking the class name. Note that ``self`` is the instance, 1461 | but Python passes that around for us automatically:: 1462 | 1463 | >>> bike = Bike(26, 34/13) 1464 | >>> print(bike.gear_inches()) 1465 | 68.0 1466 | 1467 | We can access both class attributes and instance attributes on the instance:: 1468 | 1469 | >>> bike.num_passengers 1470 | 1 1471 | 1472 | >>> bike.size 1473 | 26 1474 | 1475 | If an attribute is not found on the instance, Python will then look for it on the class, it will look through 1476 | the parent classes to continue to try and find it. If the lookup is unsuccessful, an ``AttributeError`` is raised. 1477 | 1478 | Subclasses 1479 | ------------ 1480 | 1481 | To subclass a class, simply place the parent class name in parentheses following 1482 | the class name in the declaration. We can call the ``super`` function to gain access to parent 1483 | methods:: 1484 | 1485 | >>> class Tandem(Bike): 1486 | ... num_passengers = 2 1487 | ... 1488 | ... def __init__(self, wheel_size, rings, cogs): 1489 | ... self.rings = rings 1490 | ... self.cogs = cogs 1491 | ... ratio = rings[0] / cogs[0] 1492 | ... super().__init__(wheel_size, ratio) 1493 | ... 1494 | ... def shift(self, ring_idx, cog_idx): 1495 | ... self.ratio = self.rings[ring_idx] \ 1496 | ... / self.cogs[cog_idx] 1497 | ... 1498 | 1499 | .. note:: 1500 | 1501 | In the above example, we used a ``\`` to indicate that the 1502 | line continued on the following line. This is usually required 1503 | unless there is an implicit line continuation with an opening 1504 | brace that hasn't been closed 1505 | (``(``, ``[``, or ``{``). 1506 | 1507 | The instance of the subclass can call methods that are defined on its class or the parent class:: 1508 | 1509 | >>> tan = Tandem(26, [42, 36], [24, 20, 15, 11]) 1510 | >>> tan.shift(1, -1) 1511 | >>> tan.gear_inches() 1512 | 85.0909090909091 1513 | 1514 | Class Methods and Static Methods 1515 | -------------------------------- 1516 | 1517 | The ``classmethod`` decorator is used to create methods that you 1518 | can invoke directly on the 1519 | class. This allows us to create alternate constructors. Note 1520 | that the implicit first argument is the class, commonly 1521 | named ``cls`` (as ``class`` is a keyword and will error out):: 1522 | 1523 | >>> INCHES_PER_METER = 39.37 1524 | 1525 | >>> class MountainBike(Bike): 1526 | ... @classmethod 1527 | ... def from_metric(cls, size_meters, ratio): 1528 | ... return cls(size_meters * 1529 | ... INCHES_PER_METER, 1530 | ... ratio) 1531 | 1532 | 1533 | >>> mtn = MountainBike.from_metric(.559, 38/11) 1534 | >>> mtn.gear_inches() 1535 | 76.0270490909091 1536 | 1537 | .. note:: 1538 | 1539 | In the above example, we had an implicit line continuation without a 1540 | backslash, because there was a ``(`` on the line. 1541 | 1542 | The ``staticmethod`` decorator lets you attach functions to 1543 | a class. (I don't like them, just use a function). Note 1544 | that they don't get an implicit first argument. It can be 1545 | called on the instance or the class:: 1546 | 1547 | >>> class Recumbent(Bike): 1548 | ... @staticmethod 1549 | ... def is_fast(): 1550 | ... return True 1551 | 1552 | >>> Recumbent.is_fast() 1553 | True 1554 | 1555 | >>> lawnchair = Recumbent(20, 4) 1556 | >>> lawnchair.is_fast() 1557 | True 1558 | 1559 | Properties 1560 | ---------- 1561 | 1562 | If you want to have actions occur under the covers on attribute access, 1563 | you can use properties to do that:: 1564 | 1565 | 1566 | 1567 | >>> class Person: 1568 | ... def __init__(self, name): 1569 | ... self._name = name 1570 | ... 1571 | ... @property 1572 | ... def name(self): 1573 | ... if self._name == 'Richard': 1574 | ... return 'Ringo' 1575 | ... return self._name 1576 | ... 1577 | ... @name.setter 1578 | ... def name(self, value): 1579 | ... self._name = value 1580 | ... 1581 | ... @name.deleter 1582 | ... def name(self): 1583 | ... del self._name 1584 | 1585 | Rather than calling the ``.name()`` method, we access the attribute:: 1586 | 1587 | >>> p = Person('Richard') 1588 | >>> p.name 1589 | 'Ringo' 1590 | 1591 | >>> p.name = 'Fred' 1592 | 1593 | 1594 | Data classes 1595 | ------------ 1596 | 1597 | Python 3.7 introduced data classes (PEP 557). They can describe the attributes of 1598 | a class using annotations:: 1599 | 1600 | >>> import typing 1601 | >>> from dataclasses import dataclass 1602 | >>> @dataclass 1603 | ... class Bike2: 1604 | ... num_passengers: typing.ClassVar[int] 1605 | ... wheel_size: float 1606 | ... gear_ratio: float 1607 | ... 1608 | ... def gear_inches(self): 1609 | ... return self.gear_ratio * self.wheel_size 1610 | 1611 | 1612 | 1613 | 1614 | Looping 1615 | ======= 1616 | 1617 | You can loop over objects in a sequence:: 1618 | 1619 | >>> names = ['John', 'Paul', 'Ringo'] 1620 | >>> for name in names: 1621 | ... print(name) 1622 | John 1623 | Paul 1624 | Ringo 1625 | 1626 | The ``break`` statement will pop you out of a loop:: 1627 | 1628 | >>> for name in names: 1629 | ... if name == 'Paul': 1630 | ... break 1631 | ... print(name) 1632 | John 1633 | 1634 | The ``continue`` statement skips over the body of the loop and *continues* 1635 | at the next item of iteration:: 1636 | 1637 | >>> for name in names: 1638 | ... if name == 'Paul': 1639 | ... continue 1640 | ... print(name) 1641 | John 1642 | Ringo 1643 | 1644 | You can use the ``else`` statement to indicate that every item was looped 1645 | over, and a ``break`` was never encountered:: 1646 | 1647 | >>> for name in names: 1648 | ... if name == 'George': 1649 | ... break 1650 | ... else: 1651 | ... raise ValueError("No Georges") 1652 | Traceback (most recent call last): 1653 | ... 1654 | ValueError: No Georges 1655 | 1656 | Don't loop over index values (``range(len(names))``). Use ``enumerate``:: 1657 | 1658 | >>> for i, name in enumerate(names, 1): 1659 | ... print("{}. {}".format(i, name)) 1660 | 1. John 1661 | 2. Paul 1662 | 3. Ringo 1663 | 1664 | ``while`` Loops 1665 | --------------- 1666 | 1667 | You can use ``while`` loops to create loops as well. If it is an infinite loop, 1668 | you can break out of it:: 1669 | 1670 | >>> done = False 1671 | >>> while not done: 1672 | ... # some work 1673 | ... done = True 1674 | 1675 | 1676 | You can add an ``else`` clause that only runs when the ``while`` conditional becomes false. If you break out of the loop it will not run. 1677 | 1678 | Iteration Protocol 1679 | ------------------ 1680 | 1681 | To make an iterator implement ``__iter__`` and ``__next__``:: 1682 | 1683 | >>> class fib: 1684 | ... def __init__(self, limit=None): 1685 | ... self.val1 = 1 1686 | ... self.val2 = 1 1687 | ... self.limit = limit 1688 | ... 1689 | ... def __iter__(self): 1690 | ... return self 1691 | ... 1692 | ... def __next__(self): 1693 | ... val = self.val1 1694 | ... self.val1 = self.val2 1695 | ... self.val2 = val + self.val1 1696 | ... if self.limit is not None and \ 1697 | ... val < self.limit: 1698 | ... return val 1699 | ... raise StopIteration 1700 | 1701 | 1702 | Use the iterator in a loop:: 1703 | 1704 | >>> e = fib(6) 1705 | >>> for val in e: 1706 | ... print(val) 1707 | 1 1708 | 1 1709 | 2 1710 | 3 1711 | 5 1712 | 1713 | Unrolling the protocol:: 1714 | 1715 | >>> e = fib(6) 1716 | >>> it = iter(e) # calls e.__iter__() 1717 | >>> next(it) # calls it.__next__() 1718 | 1 1719 | >>> next(it) 1720 | 1 1721 | >>> next(it) 1722 | 2 1723 | >>> next(it) 1724 | 3 1725 | >>> next(it) 1726 | 5 1727 | >>> next(it) 1728 | Traceback (most recent call last): 1729 | ... 1730 | StopIteration 1731 | 1732 | 1733 | 1734 | Conditionals 1735 | =============== 1736 | 1737 | Python has an ``if`` statement with zero or more ``elif`` statements, 1738 | and an optional ``else`` statement at the end. In Python, the word ``elif`` is Dutch for *else if*:: 1739 | 1740 | >>> grade = 72 1741 | 1742 | >>> def letter_grade(grade): 1743 | ... if grade > 90: 1744 | ... return 'A' 1745 | ... elif grade > 80: 1746 | ... return 'B' 1747 | ... elif grade > 70: 1748 | ... return 'C' 1749 | ... else: 1750 | ... return 'D' 1751 | 1752 | >>> letter_grade(grade) 1753 | 'C' 1754 | 1755 | Python supports the following tests: ``>``, ``>=``, ``<``, ``<=``, ``==``, and ``!=``. For boolean operators use ``and``, ``or``, and ``not`` (``&``, ``|``, and ``^`` are the bitwise operators). 1756 | 1757 | 1758 | Note that Python also supports *range comparisons*:: 1759 | 1760 | >>> x = 4 1761 | >>> if 3 < x < 5: 1762 | ... print("Four!") 1763 | Four! 1764 | 1765 | Python does not have a switch statement, often dictionaries are used to support a similar construct:: 1766 | 1767 | >>> def add(x, y): 1768 | ... return x + y 1769 | 1770 | >>> def sub(x, y): 1771 | ... return x - y 1772 | 1773 | >>> ops = {'+': add, '-': sub} 1774 | 1775 | >>> op = '+' 1776 | >>> a = 2 1777 | >>> b = 3 1778 | >>> ops[op](a, b) 1779 | 5 1780 | 1781 | 1782 | 1783 | Truthiness 1784 | ---------- 1785 | 1786 | You can define the ``__bool__`` method to teach your classes how to act in a boolean context. If that doesn't exists, Python will use ``__len__``, and finally default to ``True``. 1787 | 1788 | The following table lists *truthy* and *falsey* values: 1789 | 1790 | +-------------------+---------------------------------+ 1791 | | Truthy | Falsey | 1792 | +===================+=================================+ 1793 | | ``True`` | ``False`` | 1794 | +-------------------+---------------------------------+ 1795 | | Most objects | ``None`` | 1796 | +-------------------+---------------------------------+ 1797 | | ``1`` | ``0`` | 1798 | +-------------------+---------------------------------+ 1799 | | ``3.2`` | ``0.0`` | 1800 | +-------------------+---------------------------------+ 1801 | | ``[1, 2]`` | ``[]`` (empty list) | 1802 | +-------------------+---------------------------------+ 1803 | | ``{'a': 1, | ``{}`` (empty dict) | 1804 | | 'b': 2}`` | | 1805 | +-------------------+---------------------------------+ 1806 | | ``'string'`` | ``""`` (empty string) | 1807 | +-------------------+---------------------------------+ 1808 | | ``'False'`` | | 1809 | +-------------------+---------------------------------+ 1810 | | ``'0'`` | | 1811 | +-------------------+---------------------------------+ 1812 | 1813 | Short Circuiting 1814 | ---------------- 1815 | 1816 | The ``and`` statement will short circuit if it evaluates to false:: 1817 | 1818 | >>> 0 and 1/0 1819 | 0 1820 | 1821 | Likewise, the ``or`` statement will short circuit when something evaluates to true:: 1822 | 1823 | >>> 1 or 1/0 1824 | 1 1825 | 1826 | Ternary Operator 1827 | ------------------ 1828 | 1829 | Python has its own ternary operator, called a *conditional expression* (see PEP 308). These are handy as they can be used in comprehension constructs and ``lambda`` functions:: 1830 | 1831 | >>> last = 'Lennon' if band == 'Beatles' else 'Jones' 1832 | 1833 | Note that this has similar behavior to an ``if`` statement, but it is an expression, and not a statement. Python 1834 | distinguishes these two. An easy way to determine between the two, is to remember that an expression follows a ``return`` statement. Anything you can ``return`` is an expression. 1835 | 1836 | 1837 | 1838 | 1839 | 1840 | Exceptions 1841 | ============ 1842 | 1843 | Python can catch one or more exceptions (PEP 3110). You can provide a chain of different exceptions to catch if you want to react differently. 1844 | A few hints: 1845 | 1846 | * Try to keep the block of the ``try`` statement down to the code that throws exceptions 1847 | * Be specific about the exceptions that you catch 1848 | * If you want to inspect the exception, use ``as`` to create a variable to point to it 1849 | 1850 | If you use a bare ``raise`` inside of an ``except`` block, Python's traceback will point back to the 1851 | location of the original exception, rather than where it is raised from. 1852 | 1853 | :: 1854 | 1855 | >>> def avg(seq): 1856 | ... try: 1857 | ... result = sum(seq) / len(seq) 1858 | ... except ZeroDivisionError as e: 1859 | ... return None 1860 | ... except Exception: 1861 | ... raise 1862 | ... return result 1863 | 1864 | 1865 | >>> avg([1, 2, 4]) 1866 | 2.3333333333333335 1867 | 1868 | >>> avg([]) is None 1869 | True 1870 | 1871 | >>> avg('matt') 1872 | Traceback (most recent call last): 1873 | ... 1874 | TypeError: unsupported operand type(s) for +: 'int' 1875 | and 'str' 1876 | 1877 | Raising Exceptions 1878 | ------------------ 1879 | 1880 | You can raise an exception using the ``raise`` statement (PEP 3109):: 1881 | 1882 | >>> def bad_code(x): 1883 | ... raise ValueError('Bad code') 1884 | 1885 | >>> bad_code(1) 1886 | Traceback (most recent call last): 1887 | ... 1888 | ValueError: Bad code 1889 | 1890 | Decorators 1891 | ========== 1892 | 1893 | A decorator (PEP 318) allows us to insert logic before and after a function is called. You can define a decorator with a function that takes a function as input and returns a function as output. Here is the identity decorator:: 1894 | 1895 | >>> def identity(func): 1896 | ... return func 1897 | 1898 | 1899 | We can decorate a function with it like this:: 1900 | 1901 | >>> @identity 1902 | ... def add(x, y): 1903 | ... return x + y 1904 | 1905 | A more useful decorator can inject logic before and after calling the original function. To do this we create a function inside of the function and return that:: 1906 | 1907 | >>> import functools 1908 | >>> def verbose(func): 1909 | ... @functools.wraps(func) 1910 | ... def inner(*args, **kwargs): 1911 | ... print("Calling with:{} {}".format(args, 1912 | ... kwargs)) 1913 | ... res = func(*args, **kwargs) 1914 | ... print("Result:{}".format(res)) 1915 | ... return res 1916 | ... return inner 1917 | 1918 | Above, we use print functions to illustrate before/after behavior, otherwise this is very similar to identity decorator. 1919 | 1920 | There is a special syntax for applying the decorator. We put ``@`` before the decorator name and place that on a line directly above the function we wish to decorate. Using the ``@verbose`` line before a function declaration is syntactic sugar for re-assigning the variable pointing to the function to the result of calling 1921 | the decorator with the function passed into it:: 1922 | 1923 | >>> @verbose 1924 | ... def sub(x, y): 1925 | ... return x - y 1926 | 1927 | This could also be written as, ``sub = verbose(sub)``. Note that our decorated 1928 | function will still call our original function, but add in some ``print`` statements:: 1929 | 1930 | >>> sub(5, 4) 1931 | Calling with:(5, 4) {} 1932 | Result:1 1933 | 1 1934 | 1935 | As of Python 3.9 (PEP 614), any valid expression can be used as a decorator. 1936 | 1937 | Parameterized Decorators 1938 | ------------------------ 1939 | 1940 | Because we can use closures to create functions, we can use closures to create decorators as well. 1941 | This is very similar to our decorator above, but now we make a function that will 1942 | return a decorator. Based on the inputs to that function, we can control (or parameterize) 1943 | the behavior of the decorator: 1944 | 1945 | .. raw:: latex 1946 | 1947 | %\Needspace{5\baselineskip} 1948 | \clearpage 1949 | 1950 | 1951 | :: 1952 | 1953 | >>> def verbose_level(level): 1954 | ... def verbose(func): 1955 | ... @functools.wraps(func) 1956 | ... def inner(*args, **kwargs): 1957 | ... for i in range(level): # parameterized! 1958 | ... print("Calling with:{} {}".format( 1959 | ... args, kwargs)) 1960 | ... res = func(*args, **kwargs) 1961 | ... print("Result:{}".format(res)) 1962 | ... return res 1963 | ... return inner 1964 | ... return verbose 1965 | 1966 | When you decorate with parameterized decorators, the decoration looks differently, 1967 | because we need to invoke the function to create a decorator:: 1968 | 1969 | >>> @verbose_level(2) 1970 | ... def div(x, y): 1971 | ... return x/y 1972 | 1973 | >>> div(1, 5) 1974 | Calling with:(1, 5) {} 1975 | Calling with:(1, 5) {} 1976 | Result:0.2 1977 | 0.2 1978 | 1979 | 1980 | 1981 | Class Decorators and Metaclasses 1982 | ================================ 1983 | 1984 | Python allows you to dynamically create and modify classes. Class decorators and 1985 | metaclasses are two ways to do this. 1986 | 1987 | 1988 | Class Decorators 1989 | ----------------- 1990 | 1991 | You can decorate a class definition with a *class decorator* (PEP 3129). It is a function that takes a class as input and returns a class. 1992 | 1993 | :: 1994 | 1995 | >>> def add_chirp(cls): 1996 | ... 'Class decorator to add speak method' 1997 | ... def chirp(self): 1998 | ... return "CHIRP" 1999 | ... cls.speak = chirp 2000 | ... return cls 2001 | ... 2002 | >>> @add_chirp 2003 | ... class Bird: 2004 | ... pass 2005 | 2006 | >>> b = Bird() 2007 | >>> print(b.speak()) 2008 | CHIRP 2009 | 2010 | 2011 | Creating Classes with ``type`` 2012 | -------------------------------- 2013 | 2014 | You can use ``type`` to determine the type of an object, but you can also 2015 | provide the name, parents, and attributes map, and it will return a class. 2016 | 2017 | :: 2018 | 2019 | >>> def howl(self): 2020 | ... return "HOWL" 2021 | 2022 | >>> parents = () 2023 | >>> attrs_map = {'speak': howl} 2024 | >>> F = type('F', parents, attrs_map) 2025 | 2026 | >>> f = F() 2027 | >>> print(f.speak()) 2028 | HOWL 2029 | 2030 | 2031 | Metaclasses with Functions 2032 | -------------------------- 2033 | 2034 | In the class definition you can specify a metaclass (PEP 3115), which can be a 2035 | function or a class. Here is an example of a function that can 2036 | alter the class. 2037 | 2038 | :: 2039 | 2040 | >>> def meta(name, parents, attrs_map): 2041 | ... def bark(self): 2042 | ... return "WOOF!" 2043 | ... attrs_map['speak'] = bark 2044 | ... return type(name, parents, attrs_map) 2045 | 2046 | >>> class Dog(metaclass=meta): 2047 | ... pass 2048 | 2049 | >>> d = Dog() 2050 | >>> print(d.speak()) 2051 | WOOF! 2052 | 2053 | Metaclasses with Classes 2054 | ------------------------ 2055 | 2056 | You can define a class decorator and use either ``__new__`` or 2057 | ``__init__``. Typically most use ``__new__`` as it can alter 2058 | attributes like ``__slots__``. 2059 | 2060 | :: 2061 | 2062 | >>> class CatMeta(type): # Needs to subclass type 2063 | ... def __new__(cls, name, parents, attrs_map): 2064 | ... # cls is CatMeta 2065 | ... # res is the class we are creating 2066 | ... res = super().__new__(cls, name, 2067 | ... parents, attrs_map) 2068 | ... def meow(self): 2069 | ... return "MEOW" 2070 | ... res.speak = meow 2071 | ... return res 2072 | ... 2073 | ... def __init__(cls, name, parents, attrs_map): 2074 | ... super().__init__(name, parents, attrs_map) 2075 | 2076 | >>> class Cat(metaclass=CatMeta): 2077 | ... pass 2078 | 2079 | >>> c = Cat() 2080 | >>> print(c.speak()) 2081 | MEOW 2082 | 2083 | Generators 2084 | ========== 2085 | 2086 | Generators (PEP 255) are functions that suspend their state as you iterate over the results 2087 | of them. Each ``yield`` statement returns the next item of iteration and then 2088 | *freezes* the state of the function. When iteration is resumed, the function 2089 | continues from the point it was frozen. Note, that the result of calling the 2090 | function is a generator:: 2091 | 2092 | >>> def fib_gen(): 2093 | ... val1, val2 = 1, 1 2094 | ... while 1: 2095 | ... yield val1 2096 | ... val1, val2 = val2, (val1+val2) 2097 | 2098 | 2099 | We can simulate iteration by using the iteration protocol:: 2100 | 2101 | >>> gen = fib_gen() 2102 | >>> gen_iter = iter(gen) 2103 | >>> next(gen_iter) 2104 | 1 2105 | >>> next(gen_iter) 2106 | 1 2107 | >>> next(gen_iter) 2108 | 2 2109 | >>> next(gen_iter) 2110 | 3 2111 | 2112 | 2113 | 2114 | Coroutines 2115 | ========== 2116 | 2117 | The ``asyncio`` library (PEP 3153) provides asynchronous I/O in Python 3. We use ``async def`` to define a *coroutine function* (see PEP 492). The result of calling this is a *coroutine object*. Inside a coroutine we can use ``var = await future`` to suspend the coroutine and wait for ``future`` to return. We can also await another coroutine. A coroutine object may be created but isn't run until an event loop is running:: 2118 | 2119 | >>> import asyncio 2120 | >>> async def greeting(): 2121 | ... print("Here they are!") 2122 | 2123 | >>> co = greeting() 2124 | >>> co # Not running 2125 | 2126 | 2127 | >>> loop = asyncio.get_event_loop() 2128 | >>> loop.run_until_complete(co) 2129 | Here they are! 2130 | >>> loop.close() 2131 | 2132 | 2133 | .. raw:: latex 2134 | 2135 | 2136 | \clearpage 2137 | 2138 | 2139 | .. note:: 2140 | 2141 | Since Python 3.7 you can use:: 2142 | 2143 | asyncio.run(greeting()) 2144 | 2145 | instead of explicitly creating and running the loop. 2146 | 2147 | 2148 | To return an object, use an ``asyncio.Future``:: 2149 | 2150 | >>> async def compute(future): 2151 | ... print("Starting...") 2152 | ... # Simulate IO... 2153 | ... res = await answer() 2154 | ... future.set_result(res) 2155 | 2156 | 2157 | >>> async def answer(): 2158 | ... await asyncio.sleep(1) 2159 | ... return 42 2160 | 2161 | >>> f = asyncio.Future() 2162 | >>> loop = asyncio.get_event_loop() 2163 | >>> loop.run_until_complete(compute(f)) 2164 | >>> loop.close() 2165 | >>> f.result() 2166 | 42 2167 | 2168 | 2169 | .. note:: 2170 | 2171 | ``await`` and ``async`` are *soft keywords* in Python 3.6. You will get a warning if you use them for variable names. Since Python 3.7, they are reserved keywords. 2172 | 2173 | .. note:: 2174 | 2175 | For backwards compatibility in Python 3.4: 2176 | 2177 | * ``await`` can be replaced with ``yield from`` 2178 | 2179 | * ``async def`` can be replaced with a function 2180 | decorated with ``@asyncio.coroutine`` 2181 | 2182 | 2183 | 2184 | Asynchronous Generators 2185 | -------------------------- 2186 | 2187 | Python 3.6 adds asynchronous generators (PEP 525). You can use the ``yield`` 2188 | statement in an ``async def`` function:: 2189 | 2190 | >>> async def fib(): 2191 | ... v1, v2 = 1, 1 2192 | ... while True: 2193 | ... # similate io 2194 | ... await asyncio.sleep(1) 2195 | ... yield v1 2196 | ... v1, v2 = v2, v1+v2 2197 | ... if v1 > 5: 2198 | ... break 2199 | 2200 | >>> async def get_results(): 2201 | ... async for num in fib(): 2202 | ... print(num) 2203 | 2204 | >>> loop = asyncio.get_event_loop() 2205 | >>> loop.run_until_complete(get_results()) 2206 | 1 # sleeps for 1 sec before each print 2207 | 1 2208 | 2 2209 | 3 2210 | 5 2211 | >>> loop.close() 2212 | 2213 | 2214 | 2215 | 2216 | Comprehensions 2217 | ============== 2218 | 2219 | Comprehension constructs allow us to combine the functional ideas behind map and filter into an 2220 | easy to read, single line of code. When you see code that is aggregating into a list (or dict, set, or 2221 | generator), you 2222 | can replace it with a list comprehension (or dict, set comprehension, or generator expression). Here 2223 | is an example of the code smell:: 2224 | 2225 | >>> nums = range(10) 2226 | >>> result = [] 2227 | >>> for num in nums: 2228 | ... if num % 2 == 0: # filter 2229 | ... result.append(num*num) # map 2230 | 2231 | This can be specified with a list comprehension (PEP 202):: 2232 | 2233 | >>> result = [num*num for num in nums 2234 | ... if num % 2 == 0] 2235 | 2236 | To construct a list comprehension: 2237 | 2238 | * Assign the result (``result``) to brackets. The brackets signal to the 2239 | reader of the code that a list will be returned:: 2240 | 2241 | result = [ ] 2242 | 2243 | * Place the *for* loop construct inside the brackets. No colons are 2244 | necessary:: 2245 | 2246 | result = [for num in nums] 2247 | 2248 | * Insert any operations that filter the accumulation after the for 2249 | loop:: 2250 | 2251 | result = [for num in nums if num % 2 == 0] 2252 | 2253 | * Insert the accumulated object (``num*num``) at the front directly 2254 | following the left bracket. Insert parentheses around the object if 2255 | it is a tuple:: 2256 | 2257 | result = [num*num for num in nums 2258 | if num % 2 == 0] 2259 | 2260 | Set Comprehensions 2261 | ------------------ 2262 | 2263 | If you replace the ``[`` with ``{``, you will get a set comprehension (PEP 274) instead of a list comprehension:: 2264 | 2265 | >>> {num*num for num in nums if num % 2 == 0} 2266 | {0, 64, 4, 36, 16} 2267 | 2268 | Dict Comprehensions 2269 | ------------------- 2270 | 2271 | If you replace the ``[`` with ``{``, and separate the key and value with a colon, 2272 | you will get a dictionary comprehension (PEP 274):: 2273 | 2274 | >>> {num:num*num for num in nums if num % 2 == 0} 2275 | {0: 0, 2: 4, 4: 16, 6: 36, 8: 64} 2276 | 2277 | .. note:: 2278 | 2279 | Since Python 3.6, dictionaries are now ordered by key entry. Hence the ordering above. 2280 | 2281 | Generator Expressions 2282 | --------------------- 2283 | 2284 | If you replace the ``[`` with ``(``, you will get a generator instead of a list. This is called a *generator expression* (PEP 289):: 2285 | 2286 | >>> (num*num for num in nums if num % 2 == 0) 2287 | at 0x10a6f8780> 2288 | 2289 | Asynchronous Comprehensions 2290 | --------------------------- 2291 | 2292 | Python 3.6 (PEP 530) gives us *asynchronous comprehensions*. You can add ``async`` following what you are collecting to make it asynchronous. If you had the following code:: 2293 | 2294 | >>> async def process(aiter): 2295 | ... result = [] 2296 | ... async for num in aiter: 2297 | ... if num % 2 == 0: # filter 2298 | ... result.append(num*num) # map 2299 | 2300 | You could replace it with:: 2301 | 2302 | >>> async def process(aiter): 2303 | ... result = [num*num async for num in aiter 2304 | ... if num % 2 == 0] 2305 | 2306 | 2307 | 2308 | Context Managers 2309 | ================ 2310 | 2311 | If you find code where you need to make sure something happens before *and* after a block, 2312 | a context manager (PEP 343) is a convenient way to enforce that. Another code smell that indicates 2313 | you could be using a context manager is a ``try``/``finally`` block. 2314 | 2315 | Context managers can be created with functions or classes. 2316 | 2317 | If we were writing a Python module to write TeX, we might do something like this to ensure that 2318 | the environments are closed properly:: 2319 | 2320 | >>> def start(env): 2321 | ... return '\\begin{{{}}}'.format(env) 2322 | 2323 | >>> def end(env): 2324 | ... return '\\end{{{}}}'.format(env) 2325 | 2326 | >>> def may_error(): 2327 | ... import random 2328 | ... if random.random() < .5: 2329 | ... return 'content' 2330 | ... raise ValueError('Problem') 2331 | 2332 | 2333 | >>> out = [] 2334 | >>> out.append(start('center')) 2335 | 2336 | >>> try: 2337 | ... out.append(may_error()) 2338 | ... except ValueError: 2339 | ... pass 2340 | ... finally: 2341 | ... out.append(end('center')) 2342 | 2343 | This code can use a context manager to be a little cleaner. 2344 | 2345 | Function Based Context Managers 2346 | ------------------------------- 2347 | 2348 | To create a context manager with a function, decorate with 2349 | ``contextlib.contextmanager``, and yield where you want to insert your block:: 2350 | 2351 | >>> import contextlib 2352 | >>> @contextlib.contextmanager 2353 | ... def env(name, content): 2354 | ... content.append('\\begin{{{}}}'.format(name)) 2355 | ... try: 2356 | ... yield 2357 | ... except ValueError: 2358 | ... pass 2359 | ... finally: 2360 | ... content.append('\\end{{{}}}'.format(name)) 2361 | 2362 | Our code looks better now, and there will always be a closing tag:: 2363 | 2364 | >>> out = [] 2365 | >>> with env('center', out): 2366 | ... out.append(may_error()) 2367 | 2368 | >>> out 2369 | ['\\begin{center}', 'content', '\\end{center}'] 2370 | 2371 | Class Based Context Managers 2372 | ---------------------------- 2373 | 2374 | To create a class based context manager, implement the ``__enter__`` and ``__exit__`` methods:: 2375 | 2376 | >>> class env: 2377 | ... def __init__(self, name, content): 2378 | ... self.name = name 2379 | ... self.content = content 2380 | ... 2381 | ... def __enter__(self): 2382 | ... self.content.append('\\begin{{{}}}'.format( 2383 | ... self.name)) 2384 | ... 2385 | ... def __exit__(self, type, value, tb): 2386 | ... # if error in block, t, v, & tb 2387 | ... # have non None values 2388 | ... # return True to hide exception 2389 | ... self.content.append('\\end{{{}}}'.format( 2390 | ... self.name)) 2391 | ... return True 2392 | 2393 | The code looks the same as using the function based context manager:: 2394 | 2395 | >>> out = [] 2396 | >>> with env('center', out): 2397 | ... out.append(may_error()) 2398 | 2399 | >>> out # may_error had an issue 2400 | ['\\begin{center}', '\\end{center}'] 2401 | 2402 | Parenthesized context managers 2403 | --------------- 2404 | Using enclosing parentheses for continuation across multiple lines in context managers is supported since Python 3.10 (PEP 617) 2405 | Now it is possible to format long collections of context managers, in multiple lines, in a similar way as it was already possible with import statements. 2406 | 2407 | Examples of which is now valid:: 2408 | >>> with ( 2409 | ... CtxManager1() as example1, 2410 | ... CtxManager2() as example2, 2411 | ... CtxManager3() as example3, 2412 | ...): 2413 | 2414 | Context objects 2415 | --------------- 2416 | 2417 | Some context managers create objects that we can use while inside of the context. 2418 | The ``open`` context manager returns a file object:: 2419 | 2420 | with open('/tmp/test.txt') as fin: 2421 | # muck around with fin 2422 | 2423 | To create an object in a function based context manager, simply ``yield`` the object. 2424 | In a class based context manager, return the object in the ``__enter__`` method. 2425 | 2426 | Type Union Operator 2427 | =================== 2428 | Python 3.10 (PEP 605) has introduced a new type union operator overloading the ``|`` operator on types which enables the syntax ``X | Y``. 2429 | This operator lets us write "either type X or type Y" in cleaner format. 2430 | 2431 | A basic example:: 2432 | 2433 | >>> (int | str) | float == int | str | float 2434 | True 2435 | 2436 | It can also be used to apply type hints to methods accepting arguments of multiple types:: 2437 | 2438 | >>> def square(number: int | float) -> int | float: 2439 | ... return number ** 2 2440 | 2441 | The union type operator can also be passed as second argument to ``isinstance()`` and ``issubclass()`` method:: 2442 | 2443 | >>> x = 10 2444 | >>> isinstance(x, int | str) 2445 | True 2446 | 2447 | Type Annotations 2448 | =================== 2449 | 2450 | Python 3.6 (PEP 483 and 484) allows you to provide types for 2451 | input and output of functions. They can be used to: 2452 | 2453 | * Allow 3rd party libraries such as mypy [#]_ to run static typing 2454 | * Assist editors with type inference 2455 | * Aid developers in understanding code 2456 | 2457 | .. [#] http://mypy-lang.org/ 2458 | 2459 | Types can be expressed as: 2460 | 2461 | * Built-in classes 2462 | * Third party classes 2463 | * Abstract Base Classes 2464 | * Types found in the ``types`` module 2465 | * User-defined classes 2466 | 2467 | A basic example:: 2468 | 2469 | >>> def add(x: int, y: int) -> float: 2470 | ... return x + y 2471 | 2472 | >>> add(2, 3) 2473 | 5 2474 | 2475 | Note that Python does not do type checking, you need to use something like mypy:: 2476 | 2477 | >>> add("foo", "bar") 2478 | 'foobar' 2479 | 2480 | You can also specify the types of variables with a comment:: 2481 | 2482 | >>> from typing import Dict 2483 | >>> ages = {} # type: Dict[str, int] 2484 | 2485 | As of PEP 585 (Python 3.9) you type hint on built in container without using the parallel types from the ``typing`` module. You can also *parameterize* the type:: 2486 | 2487 | >>> from __future__ import annotations 2488 | >>> ages: dict[str, int] = {} 2489 | 2490 | As of PEP 604 (Python 3.10) you can use the new union operator ``|`` to define a union instead of ``typing.Union``:: 2491 | 2492 | >>> typing.List[str | int] 2493 | >>> typing.Dict[str, int | float] 2494 | 2495 | As of PEP 613 (Python 3.10) the ``typing`` module has a special value ``TypeAlias`` which allows the type alias declaration to be explicit: 2496 | >>> x = 1 # untyped global expression 2497 | >>> x: int = 1 # typed global expression 2498 | 2499 | >>> x: TypeAlias = int # type alias 2500 | >>> x: TypeAlias = “MyClass” # type alias 2501 | 2502 | The ``typing`` Module 2503 | --------------------- 2504 | 2505 | This module allows you to provide hints for: 2506 | 2507 | * Callback functions 2508 | * Generic containers 2509 | * The ``Any`` type 2510 | 2511 | To designate a class or function to not type check its annotations, use the ``@typing.no_type_check`` decorator. 2512 | 2513 | Type Checking 2514 | ------------- 2515 | 2516 | Python provides no support for type checking. You will need to install a tool like ``mypy``:: 2517 | 2518 | $ pip install mypy 2519 | $ python3 -m mypy script.py 2520 | 2521 | Scripts, Packages, and Modules 2522 | ============================== 2523 | 2524 | Scripts 2525 | --------- 2526 | 2527 | A script is a Python file that you invoke ``python`` on. Typically there is a line near 2528 | the bottom that looks like this:: 2529 | 2530 | if __name__ == '__main__': 2531 | # execute something 2532 | 2533 | This test allows you to change the code path when you execute the code versus when you import the code. 2534 | The ``__name__`` attribute of a module is set to ``'__main__'`` when you execute that module. Otherwise, 2535 | if you import the module, it will be the name of the module (without ``.py``). 2536 | 2537 | Modules 2538 | ---------- 2539 | 2540 | Modules are files that end in ``.py``. According to PEP 8, we lowercase the 2541 | module name and don't put underscores between the words in them. Any 2542 | module found in the ``PYTHONPATH`` environment variable or the ``sys.path`` 2543 | list, can be imported. 2544 | 2545 | Packages 2546 | ----------- 2547 | 2548 | A directory that has a file named ``__init__.py`` in it is a *package*. A package can 2549 | have modules in it as well as sub packages. The package should be found in 2550 | ``PYTHONPATH`` or ``sys.path`` to be imported. An example might look like this:: 2551 | 2552 | 2553 | packagename/ 2554 | __init__.py 2555 | module1.py 2556 | module2.py 2557 | subpackage/ 2558 | __init__.py 2559 | 2560 | The ``__init__.py`` module can be empty or can import code from other modules in the 2561 | package to remove nesting in import statements. 2562 | 2563 | Importing 2564 | ------------ 2565 | 2566 | You can import a package or a module:: 2567 | 2568 | import packagename 2569 | import packagename.module1 2570 | 2571 | Assume there is a ``fib`` function in ``module1``. You have access to everything in the namespace of the module you imported. To use this function you will need to use the fully qualified name, ``packagename.module1.fib``:: 2572 | 2573 | import packagename.module1 2574 | 2575 | packagename.module1.fib() 2576 | 2577 | 2578 | If you only want to import the ``fib`` function, use the ``from`` variant:: 2579 | 2580 | from packagename.module1 import fib 2581 | 2582 | fib() 2583 | 2584 | You can also rename imports using ``as``:: 2585 | 2586 | from packagename.module1 import fib as package_fib 2587 | 2588 | package_fib() 2589 | 2590 | Environments 2591 | ================ 2592 | 2593 | Python 3 includes the ``venv`` module for creating a sandbox for your project or a *virtual environment*. 2594 | 2595 | To create an environment on Unix systems, run:: 2596 | 2597 | $ python3 -m venv /path/to/env 2598 | 2599 | On Windows, run:: 2600 | 2601 | c:\> python -m venv c:\path\to\env 2602 | 2603 | To enter or *activate* the environment on Unix, run:: 2604 | 2605 | $ source /path/to/env/bin/activate 2606 | 2607 | On Windows, run:: 2608 | 2609 | c:\> c:\path\to\env\Scripts\activate.bat 2610 | 2611 | Your prompt should have the name of the active virtual environment in parentheses. 2612 | To *deactivate* an environment on both platforms, just run the following:: 2613 | 2614 | (env) $ deactivate 2615 | 2616 | Installing Packages 2617 | ------------------- 2618 | 2619 | You should now have a ``pip`` executable, that will install a package from PyPI [#]_ into your virtual environment:: 2620 | 2621 | (env) $ pip install django 2622 | 2623 | .. [#] https://pypi.python.org/pypi 2624 | 2625 | To uninstall a package run:: 2626 | 2627 | (env) $ pip uninstall django 2628 | 2629 | If you are having issues installing a package, you might want to look into alternative Python distributions such as Anaconda [#]_ that have prepackaged many harder to install packages. 2630 | 2631 | .. [#] https://docs.continuum.io/anaconda/ 2632 | 2633 | Conda 2634 | ----- 2635 | 2636 | Even though Conda [#]_ is not part of Python, it is a common tool for managing it. Here are the Conda equivalents of virtual environments and pip. The commands are the same on Windows and Unix. 2637 | 2638 | To create a Conda environment, run:: 2639 | 2640 | $ conda create --name ENV_NAME python 2641 | 2642 | To list Conda environments, run:: 2643 | 2644 | $ conda info --envs 2645 | 2646 | To activate a Conda environment, run:: 2647 | 2648 | $ conda activate ENV_NAME 2649 | 2650 | To deactivate a Conda environment, run:: 2651 | 2652 | $ conda deactivate 2653 | 2654 | To install a package, run:: 2655 | 2656 | $ conda install django 2657 | 2658 | .. [#] https://conda.io 2659 | --------------------------------------------------------------------------------