mirror of
https://github.com/rasbt/python_reference.git
synced 2025-01-18 15:27:09 +00:00
better navigation
This commit is contained in:
parent
6a3cf62414
commit
1c07f22a5f
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"metadata": {
|
||||
"name": "",
|
||||
"signature": "sha256:35f23d6f2bbaa131a262533ed080684ed53fc0260430780f248c09af8c645759"
|
||||
"signature": "sha256:1f7175fddf00a2283246009f1da253d4c1f87bc6ac35f6c2eea1b216e927254e"
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
|
@ -39,12 +39,20 @@
|
|||
"metadata": {},
|
||||
"source": [
|
||||
"<hr>\n",
|
||||
"I am really looking forward to your comments and suggestions to improve and extend this little collection! Just send me a quick note \n",
|
||||
"I am really looking forward to your comments and suggestions to improve and \n",
|
||||
"extend this little collection! Just send me a quick note \n",
|
||||
"via Twitter: [@rasbt](https://twitter.com/rasbt) \n",
|
||||
"or Email: [bluewoodtree@gmail.com](mailto:bluewoodtree@gmail.com)\n",
|
||||
"<hr>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a name=\"sections\"></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -77,12 +85,25 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='c3_class_res'></a>\n",
|
||||
"<br>\n",
|
||||
"<br>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## The C3 class resolution algorithm for multiple class inheritance"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -182,12 +203,25 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='pm_in_lists'></a>\n",
|
||||
"<br>\n",
|
||||
"<br>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## The behavior of `+=` for lists"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -215,13 +249,13 @@
|
|||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"ID of list_a 4356439144\n",
|
||||
"ID of list_a after `+= [1]` 4356439144\n",
|
||||
"ID of list_a after `list_a = list_a + [2]` 4356446112\n"
|
||||
"ID of list_a 4356429080\n",
|
||||
"ID of list_a after `+= [1]` 4356429080\n",
|
||||
"ID of list_a after `list_a = list_a + [2]` 4356453584\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 3
|
||||
"prompt_number": 2
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
|
@ -229,9 +263,22 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='datetime_module'></a>\n",
|
||||
"## `True` and `False` in the datetime module\n",
|
||||
"<a name='datetime_module'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"## `True` and `False` in the datetime module\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\"it often comes as a big surprise for programmers to find (sometimes by way of a hard-to-reproduce bug) that,\n",
|
||||
"unlike any other time value, midnight (i.e. datetime.time(0,0,0)) is False.\n",
|
||||
"A long discussion on the python-ideas mailing list shows that, while surprising,\n",
|
||||
|
@ -240,6 +287,13 @@
|
|||
"(Original source: [http://lwn.net/SubscriberLink/590299/bf73fe823974acea/](http://lwn.net/SubscriberLink/590299/bf73fe823974acea/))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
|
@ -270,9 +324,22 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='python_small_int'></a>\n",
|
||||
"## Python reuses objects for small integers - always use \"==\" for equality, \"is\" for identity\n",
|
||||
"<a name='python_small_int'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"## Python reuses objects for small integers - always use \"==\" for equality, \"is\" for identity\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This oddity occurs, because Python keeps an array of small integer objects (i.e., integers between -5 and 256, [see the doc](https://docs.python.org/2/c-api/int.html#PyInt_FromLong)).\n",
|
||||
"\n",
|
||||
"\n",
|
||||
|
@ -283,6 +350,13 @@
|
|||
"Here is a [nice article](http://python.net/%7Egoodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables) explaining it using \"boxes\" (for people with C background) and \"name tags\" (in the case of Python):"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
|
@ -403,12 +477,31 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='shallow_vs_deep'></a>\n",
|
||||
"<a name='shallow_vs_deep'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Shallow vs. deep copies if list contains other structures and objects\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"List modification of the original list does affect shallow copies, but not deep copies if the list contains compound objects."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
|
@ -476,9 +569,27 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='false_true_expressions'></a>\n",
|
||||
"## Picking `True` values from `and` and `or` expressions\n",
|
||||
"\n",
|
||||
"<a name='false_true_expressions'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Picking `True` values from `and` and `or` expressions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If both values of in a `or` expression are True, Python will select the first one, and the second one in `and` expressions\n",
|
||||
"\n",
|
||||
"Or - as a reader suggested - picture it as \n",
|
||||
|
@ -514,10 +625,23 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='def_mutable_func'></a>\n",
|
||||
"<a name='def_mutable_func'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Don't use mutable objects as default arguments for functions!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -603,10 +727,27 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='consuming_generators'></a>\n",
|
||||
"\n",
|
||||
"## Be aware of the consuming generator\n",
|
||||
"\n",
|
||||
"<a name='consuming_generators'></a>\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Be aware of the consuming generator"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Be aware using `in` checks with generators, since they won't evaluate from the beginning once a position is \"consumed\"."
|
||||
]
|
||||
},
|
||||
|
@ -671,10 +812,29 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='bool_int'></a>\n",
|
||||
"<a name='bool_int'></a>\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"## `bool` is a subclass of `int`\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Chicken or egg? In the history of Python (Python 2.2 to be specific) truth values were implemented via 1 and 0 (similar to the old C), to avoid syntax error in old (but perfectly working) code, `bool` was added as a subclass of `int` in Python 2.3.\n",
|
||||
"\n",
|
||||
"Original source: [http://www.peterbe.com/plog/bool-is-int](http://www.peterbe.com/plog/bool-is-int)"
|
||||
|
@ -711,10 +871,27 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='lambda_closure'></a>\n",
|
||||
"\n",
|
||||
"## About lambda-in-closures-and-a-loop pitfall\n",
|
||||
"\n",
|
||||
"<a name='lambda_closure'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## About lambda-in-closures-and-a-loop pitfall"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Remember the [\"consuming generators\"](consuming_generators)? This example is somewhat related, but the result might still come unexpected. \n",
|
||||
"\n",
|
||||
"(Original source: [http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html](http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html))\n",
|
||||
|
@ -785,11 +962,23 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='python_legb'></a>\n",
|
||||
"\n",
|
||||
"<a name='python_legb'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Python's LEGB scope resolution and the keywords `global` and `nonlocal`"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -947,10 +1136,23 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='immutable_tuple'></a>\n",
|
||||
"<a name='immutable_tuple'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## When mutable contents of immutable tuples aren't so mutable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -1174,10 +1376,27 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='list_generator'></a>\n",
|
||||
"\n",
|
||||
"## List comprehensions are fast, but generators are faster!?\n",
|
||||
"\n",
|
||||
"<a name='list_generator'></a>\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## List comprehensions are fast, but generators are faster!?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Not, really (or significantly, see the benchmarks below). So what's the reason to prefer one over the other?\n",
|
||||
"- use lists if you want to use list methods \n",
|
||||
"- use generators when you are dealing with huge collections to avoid memory issues"
|
||||
|
@ -1303,10 +1522,28 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='private_class'></a>\n",
|
||||
"\n",
|
||||
"<a name='private_class'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Public vs. private class methods and name mangling\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Who has not stumbled across this quote \"we are all consenting adults here\" in the Python community, yet? Unlike in other languages like C++ (sorry, there are many more, but that's I am most familiar with), we can't really protect class methods from being used outside the class. \n",
|
||||
"All we can do is to indicate methods as private to make clear that they are better not used outside the class, but it is really up to the class user, since \"we are all consenting adults here\"! \n",
|
||||
"So, when we want to \"make\" class methods private, we just put a double-underscore in front of it (same with other class members), which invokes some name mangling if we want to acess the private class member outside the class! \n",
|
||||
|
@ -1354,10 +1591,23 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='looping_pitfall'></a>\n",
|
||||
"<a name='looping_pitfall'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## The consequences of modifying a list when looping through it"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -1454,8 +1704,27 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='dynamic_binding'></a>\n",
|
||||
"## Dynamic binding and typos in variable names\n",
|
||||
"<a name='dynamic_binding'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Dynamic binding and typos in variable names\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Be careful, dynamic binding is convenient, but can also quickly become dangerous!"
|
||||
]
|
||||
},
|
||||
|
@ -1498,10 +1767,24 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='out_of_range_slicing'></a>\n",
|
||||
"<a name='out_of_range_slicing'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"## List slicing using indexes that are \"out of range\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -1565,10 +1848,24 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='unboundlocalerror'></a>\n",
|
||||
"<a name='unboundlocalerror'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"## Reusing global variable names and `UnboundLocalErrors`"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -1706,9 +2003,28 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='copy_mutable'></a>\n",
|
||||
"<a name='copy_mutable'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Creating copies of mutable objects\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Let's assume a scenario where we want to duplicate sub`list`s of values stored in another list. If we want to create independent sub`list` object, using the arithmetic multiplication operator could lead to rather unexpected (or undesired) results:"
|
||||
]
|
||||
},
|
||||
|
@ -1808,9 +2124,29 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='python_differences'></a>\n",
|
||||
"## Key differences between Python 2 and 3\n",
|
||||
"<a name='python_differences'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"## Key differences between Python 2 and 3\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"There are some good articles already that are summarizing the differences between Python 2 and 3, e.g., \n",
|
||||
"- [https://wiki.python.org/moin/Python2orPython3](https://wiki.python.org/moin/Python2orPython3)\n",
|
||||
"- [https://docs.python.org/3.0/whatsnew/3.0.html](https://docs.python.org/3.0/whatsnew/3.0.html)\n",
|
||||
|
@ -2117,10 +2453,24 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='function_annotation'></a>\n",
|
||||
"<a name='function_annotation'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"## Function annotations - What are those `->`'s in my Python code?\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"metadata": {
|
||||
"name": "",
|
||||
"signature": "sha256:35f23d6f2bbaa131a262533ed080684ed53fc0260430780f248c09af8c645759"
|
||||
"signature": "sha256:1f7175fddf00a2283246009f1da253d4c1f87bc6ac35f6c2eea1b216e927254e"
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
|
@ -39,12 +39,20 @@
|
|||
"metadata": {},
|
||||
"source": [
|
||||
"<hr>\n",
|
||||
"I am really looking forward to your comments and suggestions to improve and extend this little collection! Just send me a quick note \n",
|
||||
"I am really looking forward to your comments and suggestions to improve and \n",
|
||||
"extend this little collection! Just send me a quick note \n",
|
||||
"via Twitter: [@rasbt](https://twitter.com/rasbt) \n",
|
||||
"or Email: [bluewoodtree@gmail.com](mailto:bluewoodtree@gmail.com)\n",
|
||||
"<hr>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a name=\"sections\"></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -77,12 +85,25 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='c3_class_res'></a>\n",
|
||||
"<br>\n",
|
||||
"<br>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## The C3 class resolution algorithm for multiple class inheritance"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -182,12 +203,25 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='pm_in_lists'></a>\n",
|
||||
"<br>\n",
|
||||
"<br>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## The behavior of `+=` for lists"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -215,13 +249,13 @@
|
|||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"ID of list_a 4356439144\n",
|
||||
"ID of list_a after `+= [1]` 4356439144\n",
|
||||
"ID of list_a after `list_a = list_a + [2]` 4356446112\n"
|
||||
"ID of list_a 4356429080\n",
|
||||
"ID of list_a after `+= [1]` 4356429080\n",
|
||||
"ID of list_a after `list_a = list_a + [2]` 4356453584\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 3
|
||||
"prompt_number": 2
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
|
@ -229,9 +263,22 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='datetime_module'></a>\n",
|
||||
"## `True` and `False` in the datetime module\n",
|
||||
"<a name='datetime_module'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"## `True` and `False` in the datetime module\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\"it often comes as a big surprise for programmers to find (sometimes by way of a hard-to-reproduce bug) that,\n",
|
||||
"unlike any other time value, midnight (i.e. datetime.time(0,0,0)) is False.\n",
|
||||
"A long discussion on the python-ideas mailing list shows that, while surprising,\n",
|
||||
|
@ -240,6 +287,13 @@
|
|||
"(Original source: [http://lwn.net/SubscriberLink/590299/bf73fe823974acea/](http://lwn.net/SubscriberLink/590299/bf73fe823974acea/))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
|
@ -270,9 +324,22 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='python_small_int'></a>\n",
|
||||
"## Python reuses objects for small integers - always use \"==\" for equality, \"is\" for identity\n",
|
||||
"<a name='python_small_int'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"## Python reuses objects for small integers - always use \"==\" for equality, \"is\" for identity\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This oddity occurs, because Python keeps an array of small integer objects (i.e., integers between -5 and 256, [see the doc](https://docs.python.org/2/c-api/int.html#PyInt_FromLong)).\n",
|
||||
"\n",
|
||||
"\n",
|
||||
|
@ -283,6 +350,13 @@
|
|||
"Here is a [nice article](http://python.net/%7Egoodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables) explaining it using \"boxes\" (for people with C background) and \"name tags\" (in the case of Python):"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
|
@ -403,12 +477,31 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='shallow_vs_deep'></a>\n",
|
||||
"<a name='shallow_vs_deep'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Shallow vs. deep copies if list contains other structures and objects\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"List modification of the original list does affect shallow copies, but not deep copies if the list contains compound objects."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
|
@ -476,9 +569,27 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='false_true_expressions'></a>\n",
|
||||
"## Picking `True` values from `and` and `or` expressions\n",
|
||||
"\n",
|
||||
"<a name='false_true_expressions'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Picking `True` values from `and` and `or` expressions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If both values of in a `or` expression are True, Python will select the first one, and the second one in `and` expressions\n",
|
||||
"\n",
|
||||
"Or - as a reader suggested - picture it as \n",
|
||||
|
@ -514,10 +625,23 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='def_mutable_func'></a>\n",
|
||||
"<a name='def_mutable_func'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Don't use mutable objects as default arguments for functions!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -603,10 +727,27 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='consuming_generators'></a>\n",
|
||||
"\n",
|
||||
"## Be aware of the consuming generator\n",
|
||||
"\n",
|
||||
"<a name='consuming_generators'></a>\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Be aware of the consuming generator"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Be aware using `in` checks with generators, since they won't evaluate from the beginning once a position is \"consumed\"."
|
||||
]
|
||||
},
|
||||
|
@ -671,10 +812,29 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='bool_int'></a>\n",
|
||||
"<a name='bool_int'></a>\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"## `bool` is a subclass of `int`\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Chicken or egg? In the history of Python (Python 2.2 to be specific) truth values were implemented via 1 and 0 (similar to the old C), to avoid syntax error in old (but perfectly working) code, `bool` was added as a subclass of `int` in Python 2.3.\n",
|
||||
"\n",
|
||||
"Original source: [http://www.peterbe.com/plog/bool-is-int](http://www.peterbe.com/plog/bool-is-int)"
|
||||
|
@ -711,10 +871,27 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='lambda_closure'></a>\n",
|
||||
"\n",
|
||||
"## About lambda-in-closures-and-a-loop pitfall\n",
|
||||
"\n",
|
||||
"<a name='lambda_closure'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## About lambda-in-closures-and-a-loop pitfall"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Remember the [\"consuming generators\"](consuming_generators)? This example is somewhat related, but the result might still come unexpected. \n",
|
||||
"\n",
|
||||
"(Original source: [http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html](http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html))\n",
|
||||
|
@ -785,11 +962,23 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='python_legb'></a>\n",
|
||||
"\n",
|
||||
"<a name='python_legb'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Python's LEGB scope resolution and the keywords `global` and `nonlocal`"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -947,10 +1136,23 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='immutable_tuple'></a>\n",
|
||||
"<a name='immutable_tuple'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## When mutable contents of immutable tuples aren't so mutable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -1174,10 +1376,27 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='list_generator'></a>\n",
|
||||
"\n",
|
||||
"## List comprehensions are fast, but generators are faster!?\n",
|
||||
"\n",
|
||||
"<a name='list_generator'></a>\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## List comprehensions are fast, but generators are faster!?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Not, really (or significantly, see the benchmarks below). So what's the reason to prefer one over the other?\n",
|
||||
"- use lists if you want to use list methods \n",
|
||||
"- use generators when you are dealing with huge collections to avoid memory issues"
|
||||
|
@ -1303,10 +1522,28 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='private_class'></a>\n",
|
||||
"\n",
|
||||
"<a name='private_class'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Public vs. private class methods and name mangling\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Who has not stumbled across this quote \"we are all consenting adults here\" in the Python community, yet? Unlike in other languages like C++ (sorry, there are many more, but that's I am most familiar with), we can't really protect class methods from being used outside the class. \n",
|
||||
"All we can do is to indicate methods as private to make clear that they are better not used outside the class, but it is really up to the class user, since \"we are all consenting adults here\"! \n",
|
||||
"So, when we want to \"make\" class methods private, we just put a double-underscore in front of it (same with other class members), which invokes some name mangling if we want to acess the private class member outside the class! \n",
|
||||
|
@ -1354,10 +1591,23 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='looping_pitfall'></a>\n",
|
||||
"<a name='looping_pitfall'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## The consequences of modifying a list when looping through it"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -1454,8 +1704,27 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='dynamic_binding'></a>\n",
|
||||
"## Dynamic binding and typos in variable names\n",
|
||||
"<a name='dynamic_binding'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Dynamic binding and typos in variable names\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Be careful, dynamic binding is convenient, but can also quickly become dangerous!"
|
||||
]
|
||||
},
|
||||
|
@ -1498,10 +1767,24 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='out_of_range_slicing'></a>\n",
|
||||
"<a name='out_of_range_slicing'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"## List slicing using indexes that are \"out of range\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -1565,10 +1848,24 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='unboundlocalerror'></a>\n",
|
||||
"<a name='unboundlocalerror'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"## Reusing global variable names and `UnboundLocalErrors`"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -1706,9 +2003,28 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='copy_mutable'></a>\n",
|
||||
"<a name='copy_mutable'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Creating copies of mutable objects\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Let's assume a scenario where we want to duplicate sub`list`s of values stored in another list. If we want to create independent sub`list` object, using the arithmetic multiplication operator could lead to rather unexpected (or undesired) results:"
|
||||
]
|
||||
},
|
||||
|
@ -1808,9 +2124,29 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='python_differences'></a>\n",
|
||||
"## Key differences between Python 2 and 3\n",
|
||||
"<a name='python_differences'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"## Key differences between Python 2 and 3\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"There are some good articles already that are summarizing the differences between Python 2 and 3, e.g., \n",
|
||||
"- [https://wiki.python.org/moin/Python2orPython3](https://wiki.python.org/moin/Python2orPython3)\n",
|
||||
"- [https://docs.python.org/3.0/whatsnew/3.0.html](https://docs.python.org/3.0/whatsnew/3.0.html)\n",
|
||||
|
@ -2117,10 +2453,24 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='function_annotation'></a>\n",
|
||||
"<a name='function_annotation'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"## Function annotations - What are those `->`'s in my Python code?\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to top](#sections)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
|
Loading…
Reference in New Issue
Block a user