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