├── 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 |
--------------------------------------------------------------------------------