mirror of
https://github.com/rasbt/python_reference.git
synced 2024-11-23 20:11:13 +00:00
unorderable types update and separate python 2.x vs. 3.x section
This commit is contained in:
parent
4900267a02
commit
73979bb5e5
|
@ -18,8 +18,10 @@ A collection of useful scripts, tutorials, and other Python-related things
|
|||
|
||||
- A collection of not so obvious Python stuff you should know! [[IPython nb](http://nbviewer.ipython.org/github/rasbt/python_reference/blob/master/not_so_obvious_python_stuff.ipynb?create=1)]
|
||||
|
||||
|
||||
- Python's scope resolution for variable names and the LEGB rule [[IPython nb](http://nbviewer.ipython.org/github/rasbt/python_reference/blob/master/tutorials/scope_resolution_legb_rule.ipynb?create=1)]
|
||||
|
||||
- Key differences between Python 2.x and Python 3.x [[Markdown](./tutorials/key_differences_python2_python3.md)]
|
||||
|
||||
|
||||
- A thorough guide to SQLite database operations in Python [[Markdown](./sqlite3_howto/README.md)]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"metadata": {
|
||||
"name": "",
|
||||
"signature": "sha256:7a22f6c91e4aab51a325c721dd7674622d1acc5b4a3a038ff512c736d83bbe4a"
|
||||
"signature": "sha256:b37510e2c48c9811f7baabeff25c48a186e0e5f154b5d341f4eda6701df705e3"
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
|
@ -13,7 +13,7 @@
|
|||
"metadata": {},
|
||||
"source": [
|
||||
"[Sebastian Raschka](http://sebastianraschka.com) \n",
|
||||
"last updated: 05/03/2014 ([Changelog](#changelog))\n",
|
||||
"last updated: 05/24/2014 ([Changelog](#changelog))\n",
|
||||
"\n",
|
||||
"- [Link to this IPython Notebook on GitHub](https://github.com/rasbt/python_reference/blob/master/not_so_obvious_python_stuff.ipynb) \n",
|
||||
"- [Link to the GitHub repository](https://github.com/rasbt/python_reference) \n",
|
||||
|
@ -24,7 +24,7 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### All code was executed in Python 3.4"
|
||||
"#### All code was executed in Python 3.4 (unless stated otherwise)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -59,32 +59,59 @@
|
|||
"source": [
|
||||
"# Sections\n",
|
||||
"- [The C3 class resolution algorithm for multiple class inheritance](#c3_class_res)\n",
|
||||
"\n",
|
||||
"- [Assignment operators and lists - simple-add vs. add-AND operators](#pm_in_lists)\n",
|
||||
"\n",
|
||||
"- [`True` and `False` in the datetime module](#datetime_module)\n",
|
||||
"\n",
|
||||
"- [Python reuses objects for small integers - always use \"==\" for equality, \"is\" for identity](#python_small_int)\n",
|
||||
"\n",
|
||||
"- [Shallow vs. deep copies if list contains other structures and objects](#shallow_vs_deep)\n",
|
||||
"\n",
|
||||
"- [Picking `True` values from logical `and`s and `or`s](#false_true_expressions)\n",
|
||||
"\n",
|
||||
"- [Don't use mutable objects as default arguments for functions!](#def_mutable_func)\n",
|
||||
"\n",
|
||||
"- [Be aware of the consuming generator](#consuming_generator)\n",
|
||||
"\n",
|
||||
"- [`bool` is a subclass of `int`](#bool_int)\n",
|
||||
"\n",
|
||||
"- [About lambda-in-closures and-a-loop pitfall](#lambda_closure)\n",
|
||||
"\n",
|
||||
"- [Python's LEGB scope resolution and the keywords `global` and `nonlocal`](#python_legb)\n",
|
||||
"\n",
|
||||
"- [When mutable contents of immutable tuples aren't so mutable](#immutable_tuple)\n",
|
||||
"\n",
|
||||
"- [List comprehensions are fast, but generators are faster!?](#list_generator)\n",
|
||||
"\n",
|
||||
"- [Public vs. private class methods and name mangling](#private_class)\n",
|
||||
"\n",
|
||||
"- [The consequences of modifying a list when looping through it](#looping_pitfall)\n",
|
||||
"\n",
|
||||
"- [Dynamic binding and typos in variable names](#dynamic_binding)\n",
|
||||
"\n",
|
||||
"- [List slicing using indexes that are \"out of range](#out_of_range_slicing)\n",
|
||||
"\n",
|
||||
"- [Reusing global variable names and UnboundLocalErrors](#unboundlocalerror)\n",
|
||||
"\n",
|
||||
"- [Creating copies of mutable objects](#copy_mutable)\n",
|
||||
"\n",
|
||||
"- [Key differences between Python 2 and 3](#python_differences)\n",
|
||||
"\n",
|
||||
"- [Function annotations - What are those `->`'s in my Python code?](#function_annotation)\n",
|
||||
"\n",
|
||||
"- [Abortive statements in `finally` blocks](#finally_blocks)\n",
|
||||
"\n",
|
||||
"- [Assigning types to variables as values](#variable_types)\n",
|
||||
"\n",
|
||||
"- [Only the first clause of generators is evaluated immediately](#generator_rhs)\n",
|
||||
"\n",
|
||||
"- [Keyword argument unpacking syntax - `*args` and `**kwargs`](#splat_op)\n",
|
||||
"\n",
|
||||
"- [Metaclasses - What creates a new instance of a class?](#new_instance)\n",
|
||||
"\n",
|
||||
"- [Else-clauses: \"conditional else\" and \"completion else\"](#else_clauses)\n",
|
||||
"\n",
|
||||
"- [Interning of compile-time constants vs. run-time expressions](#string_interning)"
|
||||
]
|
||||
},
|
||||
|
@ -2282,12 +2309,69 @@
|
|||
"(Note: the the code was executed in Python 3.4.0 and Python 2.7.5 and copied from interactive shell sessions.)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a id='py23_overview'></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Overview - Key differences between Python 2 and 3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"\n",
|
||||
"- [Unicode](#unicode)\n",
|
||||
"- [The print statement](#print)\n",
|
||||
"- [Integer division](#integer_div)\n",
|
||||
"- [xrange()](#xrange)\n",
|
||||
"- [Raising exceptions](#raising_exceptions)\n",
|
||||
"- [Handling exceptions](#handling_exceptions)\n",
|
||||
"- [next() function and .next() method](#next_next)\n",
|
||||
"- [Loop variables and leaking into the global scope](#loop_leak)\n",
|
||||
"- [Comparing unorderable types](#compare_unorder)\n",
|
||||
"\n",
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a id='unicode'></a>\n",
|
||||
"<br>\n",
|
||||
"<br>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Unicode..."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to Python 2.x vs 3.x overview](#py23_overview)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"### Unicode...\n",
|
||||
"####- Python 2: \n",
|
||||
"We have ASCII `str()` types, separate `unicode()`, but no `byte` type\n",
|
||||
"####- Python 3: \n",
|
||||
|
@ -2341,7 +2425,29 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### The print statement\n",
|
||||
"<a id='print'></a>\n",
|
||||
"<br>\n",
|
||||
"<br>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### The print statement"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to Python 2.x vs 3.x overview](#py23_overview)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Very trivial, but this change makes sense, Python 3 now only accepts `print`s with proper parentheses - just like the other function calls ..."
|
||||
]
|
||||
},
|
||||
|
@ -2395,7 +2501,29 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Integer division\n",
|
||||
"<a id='integer_div'></a>\n",
|
||||
"<br>\n",
|
||||
"<br>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Integer division"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to Python 2.x vs 3.x overview](#py23_overview)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This is a pretty dangerous thing if you are porting code, or executing Python 3 code in Python 2 since the change in integer-division behavior can often go unnoticed. \n",
|
||||
"So, I still tend to use a `float(3)/2` or `3/2.0` instead of a `3/2` in my Python 3 scripts to save the Python 2 guys some trouble ... (PS: and vice versa, you can `from __future__ import division` in your Python 2 scripts)."
|
||||
]
|
||||
|
@ -2432,7 +2560,30 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### `xrange()` \n",
|
||||
"<a id='xrange'></a>\n",
|
||||
"<br>\n",
|
||||
"<br>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"###`xrange()` "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to Python 2.x vs 3.x overview](#py23_overview)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
" \n",
|
||||
"`xrange()` was pretty popular in Python 2.x if you wanted to create an iterable object. The behavior was quite similar to a generator ('lazy evaluation'), but you could iterate over it infinitely. The advantage was that it was generally faster than `range()` (e.g., in a for-loop) - not if you had to iterate over the list multiple times, since the generation happens every time from scratch! \n",
|
||||
"In Python 3, the `range()` was implemented like the `xrange()` function so that a dedicated `xrange()` function does not exist anymore."
|
||||
]
|
||||
|
@ -2470,7 +2621,30 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Raising exceptions\n",
|
||||
"<a id='raising_exceptions'></a>\n",
|
||||
"<br>\n",
|
||||
"<br>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Raising exceptions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to Python 2.x vs 3.x overview](#py23_overview)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"\n",
|
||||
"Where Python 2 accepts both notations, the 'old' and the 'new' way, Python 3 chokes (and raises a `SyntaxError` in turn) if we don't enclose the exception argument in parentheses:"
|
||||
]
|
||||
|
@ -2509,9 +2683,32 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Handling exceptions\n",
|
||||
"<a id='handling_exceptions'></a>\n",
|
||||
"<br>\n",
|
||||
"<br>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Handling exceptions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to Python 2.x vs 3.x overview](#py23_overview)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"Also the handling of excecptions has slightly changed in Python 3. Now, we have to use the `as` keyword!"
|
||||
"\n",
|
||||
"Also the handling of exceptions has slightly changed in Python 3. Now, we have to use the `as` keyword!"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -2538,11 +2735,37 @@
|
|||
"metadata": {},
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"<a id='next_next'></a>\n",
|
||||
"<br>\n",
|
||||
"<br>"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### The `next()` function and `.next()` method\n",
|
||||
"### The `next()` function and `.next()` method"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to Python 2.x vs 3.x overview](#py23_overview)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"\n",
|
||||
"Where you can use both function and method in Python 2.7.5, the `next()` function is all that remain in Python 3!"
|
||||
]
|
||||
|
@ -2575,7 +2798,23 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### In Python 3.x for-loop variables don't leak into the global namespace anymore"
|
||||
"<a id='loop_leak'></a>\n",
|
||||
"<br>\n",
|
||||
"<br>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### In Python 3.x for-loop variables don't leak into the global namespace anymore"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to Python 2.x vs 3.x overview](#py23_overview)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -2591,6 +2830,9 @@
|
|||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"from platform import python_version\n",
|
||||
"print('This code cell was executed in Python', python_version())\n",
|
||||
"\n",
|
||||
"i = 1\n",
|
||||
"print([i for i in range(5)])\n",
|
||||
"print(i, '-> i in global')"
|
||||
|
@ -2602,21 +2844,124 @@
|
|||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"This code cell was executed in Python 3.3.5\n",
|
||||
"[0, 1, 2, 3, 4]\n",
|
||||
"1 -> i in global\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 1
|
||||
"prompt_number": 4
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"from platform import python_version\n",
|
||||
"print 'This code cell was executed in Python', python_version()\n",
|
||||
"\n",
|
||||
"i = 1\n",
|
||||
"print [i for i in range(5)]\n",
|
||||
"print i, '-> i in global' "
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"This code cell was executed in Python 2.7.6\n",
|
||||
"[0, 1, 2, 3, 4]\n",
|
||||
"4 -> i in global\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 9
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"In Python 2.x this would print \n",
|
||||
"`4 -> i in global`"
|
||||
"<a id='compare_unorder'></a>\n",
|
||||
"<br>\n",
|
||||
"<br>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Python 3.x prevents us from comparing unorderable types"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[[back to Python 2.x vs 3.x overview](#py23_overview)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"from platform import python_version\n",
|
||||
"print 'This code cell was executed in Python', python_version()\n",
|
||||
"\n",
|
||||
"print [1, 2] > 'foo'\n",
|
||||
"print (1, 2) > 'foo'\n",
|
||||
"print [1, 2] > (1, 2)"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"This code cell was executed in Python 2.7.6\n",
|
||||
"False\n",
|
||||
"True\n",
|
||||
"False\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 8
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"from platform import python_version\n",
|
||||
"print('This code cell was executed in Python', python_version())\n",
|
||||
"\n",
|
||||
"print([1, 2] > 'foo')\n",
|
||||
"print((1, 2) > 'foo')\n",
|
||||
"print([1, 2] > (1, 2))"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"This code cell was executed in Python 3.3.5\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ename": "TypeError",
|
||||
"evalue": "unorderable types: list() > str()",
|
||||
"output_type": "pyerr",
|
||||
"traceback": [
|
||||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
|
||||
"\u001b[0;32m<ipython-input-3-1d774c677f73>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'This code cell was executed in Python'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpython_version\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;34m'foo'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;34m'foo'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
||||
"\u001b[0;31mTypeError\u001b[0m: unorderable types: list() > str()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 3
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -3936,6 +4281,10 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### 05/24/2014\n",
|
||||
"- new section: unorderable types in Python 2\n",
|
||||
"- table of contents for the Python 2 vs. Python 3 topic\n",
|
||||
" \n",
|
||||
"#### 05/03/2014\n",
|
||||
"- new section: else clauses: conditional vs. completion\n",
|
||||
"- new section: Interning of compile-time constants vs. run-time expressions\n",
|
||||
|
|
411
tutorials/key_differences_between_python_2_and_3.md
Normal file
411
tutorials/key_differences_between_python_2_and_3.md
Normal file
|
@ -0,0 +1,411 @@
|
|||
[Sebastian Raschka](http://sebastianraschka.com)
|
||||
last updated: 05/24/2014
|
||||
|
||||
<br>
|
||||
|
||||
**This is a subsection of ["A collection of not-so-obvious Python stuff you should know!"](http://nbviewer.ipython.org/github/rasbt/python_reference/blob/master/not_so_obvious_python_stuff.ipynb?create=1)**
|
||||
|
||||
<a id='sections'></a>
|
||||
|
||||
<br>
|
||||
|
||||
## Key differences between Python 2 and 3
|
||||
<br>
|
||||
|
||||
There are some good articles already that are summarizing the differences between Python 2 and 3, e.g.,
|
||||
- [https://wiki.python.org/moin/Python2orPython3](https://wiki.python.org/moin/Python2orPython3)
|
||||
- [https://docs.python.org/3.0/whatsnew/3.0.html](https://docs.python.org/3.0/whatsnew/3.0.html)
|
||||
- [http://python3porting.com/differences.html](http://python3porting.com/differences.html)
|
||||
- [https://docs.python.org/3/howto/pyporting.html](https://docs.python.org/3/howto/pyporting.html)
|
||||
etc.
|
||||
|
||||
But it might be still worthwhile, especially for Python newcomers, to take a look at some of those!
|
||||
(Note: the the code was executed in Python 3.4.0 and Python 2.7.5 and copied from interactive shell sessions.)
|
||||
|
||||
<a id='py23_overview'></a>
|
||||
|
||||
<br>
|
||||
|
||||
### Overview - Key differences between Python 2 and 3
|
||||
|
||||
|
||||
|
||||
|
||||
- [Unicode](#unicode)
|
||||
- [The print statement](#print)
|
||||
- [Integer division](#integer_div)
|
||||
- [xrange()](#xrange)
|
||||
- [Raising exceptions](#raising_exceptions)
|
||||
- [Handling exceptions](#handling_exceptions)
|
||||
- [next() function and .next() method](#next_next)
|
||||
- [Loop variables and leaking into the global scope](#loop_leak)
|
||||
- [Comparing unorderable types](#compare_unorder)
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
|
||||
<a id='unicode'></a>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
### Unicode...
|
||||
|
||||
[[back to Python 2.x vs 3.x overview](#py23_overview)]
|
||||
|
||||
|
||||
####- Python 2:
|
||||
We have ASCII `str()` types, separate `unicode()`, but no `byte` type
|
||||
####- Python 3:
|
||||
Now, we finally have Unicode (utf-8) `str`ings, and 2 byte classes: `byte` and `bytearray`s
|
||||
|
||||
<br>
|
||||
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">#############</span>
|
||||
<span style="color: #888888"># Python 2</span>
|
||||
<span style="color: #888888">#############</span>
|
||||
|
||||
<span style="color: #333333">>>></span> <span style="color: #007020">type</span>(unicode(<span style="background-color: #fff0f0">'is like a python3 str()'</span>))
|
||||
<span style="color: #333333"><</span><span style="color: #007020">type</span> <span style="background-color: #fff0f0">'unicode'</span><span style="color: #333333">></span>
|
||||
|
||||
<span style="color: #333333">>>></span> <span style="color: #007020">type</span>(b<span style="background-color: #fff0f0">'byte type does not exist'</span>)
|
||||
<span style="color: #333333"><</span><span style="color: #007020">type</span> <span style="background-color: #fff0f0">'str'</span><span style="color: #333333">></span>
|
||||
|
||||
<span style="color: #333333">>>></span> <span style="background-color: #fff0f0">'they are really'</span> <span style="color: #333333">+</span> b<span style="background-color: #fff0f0">' the same'</span>
|
||||
<span style="background-color: #fff0f0">'they are really the same'</span>
|
||||
|
||||
<span style="color: #333333">>>></span> <span style="color: #007020">type</span>(<span style="color: #007020">bytearray</span>(b<span style="background-color: #fff0f0">'bytearray oddly does exist though'</span>))
|
||||
<span style="color: #333333"><</span><span style="color: #007020">type</span> <span style="background-color: #fff0f0">'bytearray'</span><span style="color: #333333">></span>
|
||||
|
||||
<span style="color: #888888">#############</span>
|
||||
<span style="color: #888888"># Python 3</span>
|
||||
<span style="color: #888888">#############</span>
|
||||
|
||||
<span style="color: #333333">>>></span> <span style="color: #007020">print</span>(<span style="background-color: #fff0f0">'strings are now utf-8 </span><span style="color: #666666; font-weight: bold; background-color: #fff0f0">\u03BC</span><span style="background-color: #fff0f0">nico</span><span style="color: #666666; font-weight: bold; background-color: #fff0f0">\u0394</span><span style="background-color: #fff0f0">é!'</span>)
|
||||
strings are now utf<span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">8</span> μnicoΔé<span style="color: #FF0000; background-color: #FFAAAA">!</span>
|
||||
|
||||
|
||||
<span style="color: #333333">>>></span> <span style="color: #007020">type</span>(b<span style="background-color: #fff0f0">' and we have byte types for storing data'</span>)
|
||||
<span style="color: #333333"><</span><span style="color: #008800; font-weight: bold">class</span> <span style="color: #FF0000; background-color: #FFAAAA">'</span><span style="color: #BB0066; font-weight: bold">bytes</span><span style="background-color: #fff0f0">'></span>
|
||||
|
||||
<span style="color: #333333">>>></span> <span style="color: #007020">type</span>(<span style="color: #007020">bytearray</span>(b<span style="background-color: #fff0f0">'but also bytearrays for those who prefer them over strings'</span>))
|
||||
<span style="color: #333333"><</span><span style="color: #008800; font-weight: bold">class</span> <span style="color: #FF0000; background-color: #FFAAAA">'</span><span style="color: #BB0066; font-weight: bold">bytearray</span><span style="background-color: #fff0f0">'></span>
|
||||
|
||||
<span style="color: #333333">>>></span> <span style="background-color: #fff0f0">'string'</span> <span style="color: #333333">+</span> b<span style="background-color: #fff0f0">'bytes for data'</span>
|
||||
Traceback (most recent call last):s
|
||||
File <span style="background-color: #fff0f0">"<stdin>"</span>, line <span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #000000; font-weight: bold">in</span> <span style="color: #333333"><</span>module<span style="color: #333333">></span>
|
||||
<span style="color: #FF0000; font-weight: bold">TypeError</span>: Can<span style="background-color: #fff0f0">'t convert '</span><span style="color: #007020">bytes</span><span style="background-color: #fff0f0">' object to str implicitly</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<a id='print'></a>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
### The print statement
|
||||
|
||||
[[back to Python 2.x vs 3.x overview](#py23_overview)]
|
||||
|
||||
Very trivial, but this change makes sense, Python 3 now only accepts `print`s with proper parentheses - just like the other function calls ...
|
||||
|
||||
<br>
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Python 2</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #007020">print</span> <span style="background-color: #fff0f0">'Hello, World!'</span>
|
||||
Hello, World<span style="color: #FF0000; background-color: #FFAAAA">!</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #007020">print</span>(<span style="background-color: #fff0f0">'Hello, World!'</span>)
|
||||
Hello, World<span style="color: #FF0000; background-color: #FFAAAA">!</span>
|
||||
|
||||
<span style="color: #888888"># Python 3</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #007020">print</span>(<span style="background-color: #fff0f0">'Hello, World!'</span>)
|
||||
Hello, World<span style="color: #FF0000; background-color: #FFAAAA">!</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #007020">print</span> <span style="background-color: #fff0f0">'Hello, World!'</span>
|
||||
File <span style="background-color: #fff0f0">"<stdin>"</span>, line <span style="color: #0000DD; font-weight: bold">1</span>
|
||||
<span style="color: #007020">print</span> <span style="background-color: #fff0f0">'Hello, World!'</span>
|
||||
<span style="color: #333333">^</span>
|
||||
<span style="color: #FF0000; font-weight: bold">SyntaxError</span>: invalid syntax
|
||||
</pre></div>
|
||||
|
||||
<br>
|
||||
|
||||
And if we want to print the output of 2 consecutive print functions on the same line, you would use a comma in Python 2, and a `end=""` in Python 3:
|
||||
|
||||
<br>
|
||||
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Python 2</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #007020">print</span> <span style="background-color: #fff0f0">"line 1"</span>, ; <span style="color: #007020">print</span> <span style="background-color: #fff0f0">'same line'</span>
|
||||
line <span style="color: #0000DD; font-weight: bold">1</span> same line
|
||||
|
||||
<span style="color: #888888"># Python 3</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #007020">print</span>(<span style="background-color: #fff0f0">"line 1"</span>, end<span style="color: #333333">=</span><span style="background-color: #fff0f0">""</span>) ; <span style="color: #007020">print</span> (<span style="background-color: #fff0f0">" same line"</span>)
|
||||
line <span style="color: #0000DD; font-weight: bold">1</span> same line
|
||||
</pre></div>
|
||||
|
||||
|
||||
<a id='integer_div'></a>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
### Integer division
|
||||
|
||||
[[back to Python 2.x vs 3.x overview](#py23_overview)]
|
||||
|
||||
|
||||
This is a pretty dangerous thing if you are porting code, or executing Python 3 code in Python 2 since the change in integer-division behavior can often go unnoticed.
|
||||
So, I still tend to use a `float(3)/2` or `3/2.0` instead of a `3/2` in my Python 3 scripts to save the Python 2 guys some trouble ... (PS: and vice versa, you can `from __future__ import division` in your Python 2 scripts).
|
||||
|
||||
<br>
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Python 2</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">/</span> <span style="color: #0000DD; font-weight: bold">2</span>
|
||||
<span style="color: #0000DD; font-weight: bold">1</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">//</span> <span style="color: #0000DD; font-weight: bold">2</span>
|
||||
<span style="color: #0000DD; font-weight: bold">1</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">/</span> <span style="color: #6600EE; font-weight: bold">2.0</span>
|
||||
<span style="color: #6600EE; font-weight: bold">1.5</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">//</span> <span style="color: #6600EE; font-weight: bold">2.0</span>
|
||||
<span style="color: #6600EE; font-weight: bold">1.0</span>
|
||||
|
||||
<span style="color: #888888"># Python 3</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">/</span> <span style="color: #0000DD; font-weight: bold">2</span>
|
||||
<span style="color: #6600EE; font-weight: bold">1.5</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">//</span> <span style="color: #0000DD; font-weight: bold">2</span>
|
||||
<span style="color: #0000DD; font-weight: bold">1</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">/</span> <span style="color: #6600EE; font-weight: bold">2.0</span>
|
||||
<span style="color: #6600EE; font-weight: bold">1.5</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">//</span> <span style="color: #6600EE; font-weight: bold">2.0</span>
|
||||
<span style="color: #6600EE; font-weight: bold">1.0</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<a id='xrange'></a>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
###`xrange()`
|
||||
|
||||
[[back to Python 2.x vs 3.x overview](#py23_overview)]
|
||||
|
||||
|
||||
`xrange()` was pretty popular in Python 2.x if you wanted to create an iterable object. The behavior was quite similar to a generator ('lazy evaluation'), but you could iterate over it infinitely. The advantage was that it was generally faster than `range()` (e.g., in a for-loop) - not if you had to iterate over the list multiple times, since the generation happens every time from scratch!
|
||||
In Python 3, the `range()` was implemented like the `xrange()` function so that a dedicated `xrange()` function does not exist anymore.
|
||||
|
||||
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Python 2</span>
|
||||
<span style="color: #333333">></span> python <span style="color: #333333">-</span>m timeit <span style="background-color: #fff0f0">'for i in range(1000000):'</span> <span style="background-color: #fff0f0">' pass'</span>
|
||||
<span style="color: #0000DD; font-weight: bold">10</span> loops, best of <span style="color: #0000DD; font-weight: bold">3</span>: <span style="color: #0000DD; font-weight: bold">66</span> msec per loop
|
||||
|
||||
<span style="color: #333333">></span> python <span style="color: #333333">-</span>m timeit <span style="background-color: #fff0f0">'for i in xrange(1000000):'</span> <span style="background-color: #fff0f0">' pass'</span>
|
||||
<span style="color: #0000DD; font-weight: bold">10</span> loops, best of <span style="color: #0000DD; font-weight: bold">3</span>: <span style="color: #6600EE; font-weight: bold">27.8</span> msec per loop
|
||||
|
||||
<span style="color: #888888"># Python 3</span>
|
||||
<span style="color: #333333">></span> python3 <span style="color: #333333">-</span>m timeit <span style="background-color: #fff0f0">'for i in range(1000000):'</span> <span style="background-color: #fff0f0">' pass'</span>
|
||||
<span style="color: #0000DD; font-weight: bold">10</span> loops, best of <span style="color: #0000DD; font-weight: bold">3</span>: <span style="color: #6600EE; font-weight: bold">51.1</span> msec per loop
|
||||
|
||||
<span style="color: #333333">></span> python3 <span style="color: #333333">-</span>m timeit <span style="background-color: #fff0f0">'for i in xrange(1000000):'</span> <span style="background-color: #fff0f0">' pass'</span>
|
||||
Traceback (most recent call last):
|
||||
File <span style="background-color: #fff0f0">"/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/timeit.py"</span>, line <span style="color: #0000DD; font-weight: bold">292</span>, <span style="color: #000000; font-weight: bold">in</span> main
|
||||
x <span style="color: #333333">=</span> t<span style="color: #333333">.</span>timeit(number)
|
||||
File <span style="background-color: #fff0f0">"/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/timeit.py"</span>, line <span style="color: #0000DD; font-weight: bold">178</span>, <span style="color: #000000; font-weight: bold">in</span> timeit
|
||||
timing <span style="color: #333333">=</span> <span style="color: #007020">self</span><span style="color: #333333">.</span>inner(it, <span style="color: #007020">self</span><span style="color: #333333">.</span>timer)
|
||||
File <span style="background-color: #fff0f0">"<timeit-src>"</span>, line <span style="color: #0000DD; font-weight: bold">6</span>, <span style="color: #000000; font-weight: bold">in</span> inner
|
||||
<span style="color: #008800; font-weight: bold">for</span> i <span style="color: #000000; font-weight: bold">in</span> xrange(<span style="color: #0000DD; font-weight: bold">1000000</span>):
|
||||
<span style="color: #FF0000; font-weight: bold">NameError</span>: name <span style="background-color: #fff0f0">'xrange'</span> <span style="color: #000000; font-weight: bold">is</span> <span style="color: #000000; font-weight: bold">not</span> defined
|
||||
</pre></div>
|
||||
|
||||
|
||||
<a id='raising_exceptions'></a>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
### Raising exceptions
|
||||
|
||||
[[back to Python 2.x vs 3.x overview](#py23_overview)]
|
||||
|
||||
|
||||
|
||||
Where Python 2 accepts both notations, the 'old' and the 'new' way, Python 3 chokes (and raises a `SyntaxError` in turn) if we don't enclose the exception argument in parentheses:
|
||||
|
||||
<br>
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Python 2</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #008800; font-weight: bold">raise</span> <span style="color: #FF0000; font-weight: bold">IOError</span>, <span style="background-color: #fff0f0">"file error"</span>
|
||||
Traceback (most recent call last):
|
||||
File <span style="background-color: #fff0f0">"<stdin>"</span>, line <span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #000000; font-weight: bold">in</span> <span style="color: #333333"><</span>module<span style="color: #333333">></span>
|
||||
<span style="color: #FF0000; font-weight: bold">IOError</span>: file error
|
||||
<span style="color: #333333">>>></span> <span style="color: #008800; font-weight: bold">raise</span> <span style="color: #FF0000; font-weight: bold">IOError</span>(<span style="background-color: #fff0f0">"file error"</span>)
|
||||
Traceback (most recent call last):
|
||||
File <span style="background-color: #fff0f0">"<stdin>"</span>, line <span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #000000; font-weight: bold">in</span> <span style="color: #333333"><</span>module<span style="color: #333333">></span>
|
||||
<span style="color: #FF0000; font-weight: bold">IOError</span>: file error
|
||||
|
||||
|
||||
<span style="color: #888888"># Python 3 </span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #008800; font-weight: bold">raise</span> <span style="color: #FF0000; font-weight: bold">IOError</span>, <span style="background-color: #fff0f0">"file error"</span>
|
||||
File <span style="background-color: #fff0f0">"<stdin>"</span>, line <span style="color: #0000DD; font-weight: bold">1</span>
|
||||
<span style="color: #008800; font-weight: bold">raise</span> <span style="color: #FF0000; font-weight: bold">IOError</span>, <span style="background-color: #fff0f0">"file error"</span>
|
||||
<span style="color: #333333">^</span>
|
||||
<span style="color: #FF0000; font-weight: bold">SyntaxError</span>: invalid syntax
|
||||
<span style="color: #333333">>>></span> <span style="color: #008800; font-weight: bold">raise</span> <span style="color: #FF0000; font-weight: bold">IOError</span>(<span style="background-color: #fff0f0">"file error"</span>)
|
||||
Traceback (most recent call last):
|
||||
File <span style="background-color: #fff0f0">"<stdin>"</span>, line <span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #000000; font-weight: bold">in</span> <span style="color: #333333"><</span>module<span style="color: #333333">></span>
|
||||
<span style="color: #FF0000; font-weight: bold">OSError</span>: file error
|
||||
</pre></div>
|
||||
|
||||
|
||||
<a id='handling_exceptions'></a>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
### Handling exceptions
|
||||
|
||||
[[back to Python 2.x vs 3.x overview](#py23_overview)]
|
||||
|
||||
|
||||
|
||||
Also the handling of exceptions has slightly changed in Python 3. Now, we have to use the `as` keyword!
|
||||
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Python 2</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #008800; font-weight: bold">try</span>:
|
||||
<span style="color: #333333">...</span> blabla
|
||||
<span style="color: #333333">...</span> <span style="color: #008800; font-weight: bold">except</span> <span style="color: #FF0000; font-weight: bold">NameError</span>, err:
|
||||
<span style="color: #333333">...</span> <span style="color: #007020">print</span> err, <span style="background-color: #fff0f0">'--> our error msg'</span>
|
||||
<span style="color: #333333">...</span>
|
||||
name <span style="background-color: #fff0f0">'blabla'</span> <span style="color: #000000; font-weight: bold">is</span> <span style="color: #000000; font-weight: bold">not</span> defined <span style="color: #333333">--></span> our error msg
|
||||
|
||||
<span style="color: #888888"># Python 3</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #008800; font-weight: bold">try</span>:
|
||||
<span style="color: #333333">...</span> blabla
|
||||
<span style="color: #333333">...</span> <span style="color: #008800; font-weight: bold">except</span> <span style="color: #FF0000; font-weight: bold">NameError</span> <span style="color: #008800; font-weight: bold">as</span> err:
|
||||
<span style="color: #333333">...</span> <span style="color: #007020">print</span>(err, <span style="background-color: #fff0f0">'--> our error msg'</span>)
|
||||
<span style="color: #333333">...</span>
|
||||
name <span style="background-color: #fff0f0">'blabla'</span> <span style="color: #000000; font-weight: bold">is</span> <span style="color: #000000; font-weight: bold">not</span> defined <span style="color: #333333">--></span> our error msg
|
||||
</pre></div>
|
||||
|
||||
|
||||
<a id='next_next'></a>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
### The `next()` function and `.next()` method
|
||||
|
||||
[[back to Python 2.x vs 3.x overview](#py23_overview)]
|
||||
|
||||
Where you can use both function and method in Python 2.7.5, the `next()` function is all that remain in Python 3!
|
||||
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Python 2</span>
|
||||
<span style="color: #333333">>>></span> my_generator <span style="color: #333333">=</span> (letter <span style="color: #008800; font-weight: bold">for</span> letter <span style="color: #000000; font-weight: bold">in</span> <span style="background-color: #fff0f0">'abcdefg'</span>)
|
||||
<span style="color: #333333">>>></span> my_generator<span style="color: #333333">.</span>next()
|
||||
<span style="background-color: #fff0f0">'a'</span>
|
||||
<span style="color: #333333">>>></span> <span style="color: #007020">next</span>(my_generator)
|
||||
<span style="background-color: #fff0f0">'b'</span>
|
||||
|
||||
<span style="color: #888888"># Python 3</span>
|
||||
<span style="color: #333333">>>></span> my_generator <span style="color: #333333">=</span> (letter <span style="color: #008800; font-weight: bold">for</span> letter <span style="color: #000000; font-weight: bold">in</span> <span style="background-color: #fff0f0">'abcdefg'</span>)
|
||||
<span style="color: #333333">>>></span> <span style="color: #007020">next</span>(my_generator)
|
||||
<span style="background-color: #fff0f0">'a'</span>
|
||||
<span style="color: #333333">>>></span> my_generator<span style="color: #333333">.</span>next()
|
||||
Traceback (most recent call last):
|
||||
File <span style="background-color: #fff0f0">"<stdin>"</span>, line <span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #000000; font-weight: bold">in</span> <span style="color: #333333"><</span>module<span style="color: #333333">></span>
|
||||
<span style="color: #FF0000; font-weight: bold">AttributeError</span>: <span style="background-color: #fff0f0">'generator'</span> <span style="color: #007020">object</span> has no attribute <span style="background-color: #fff0f0">'next'</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<a id='loop_leak'></a>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
### In Python 3.x for-loop variables don't leak into the global namespace anymore
|
||||
|
||||
[[back to Python 2.x vs 3.x overview](#py23_overview)]
|
||||
|
||||
This goes back to a change that was made in Python 3.x and is described in [What’s New In Python 3.0](https://docs.python.org/3/whatsnew/3.0.html) as follows:
|
||||
|
||||
"List comprehensions no longer support the syntactic form `[... for var in item1, item2, ...]`. Use `[... for var in (item1, item2, ...)]` instead. Also note that list comprehensions have different semantics: they are closer to syntactic sugar for a generator expression inside a `list()` constructor, and in particular the loop control variables are no longer leaked into the surrounding scope."
|
||||
|
||||
<br>
|
||||
`[In:]`
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">from</span> <span style="color: #0e84b5; font-weight: bold">platform</span> <span style="color: #008800; font-weight: bold">import</span> python_version
|
||||
<span style="color: #007020">print</span>(<span style="background-color: #fff0f0">'This code cell was executed in Python'</span>, python_version())
|
||||
|
||||
i <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">1</span>
|
||||
<span style="color: #007020">print</span>([i <span style="color: #008800; font-weight: bold">for</span> i <span style="color: #000000; font-weight: bold">in</span> <span style="color: #007020">range</span>(<span style="color: #0000DD; font-weight: bold">5</span>)])
|
||||
<span style="color: #007020">print</span>(i, <span style="background-color: #fff0f0">'-> i in global'</span>)
|
||||
</pre></div>
|
||||
|
||||
<br>
|
||||
`[Out:]`
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">This code cell was executed in Python 3.3.5
|
||||
[0, 1, 2, 3, 4]
|
||||
1 -> i in global
|
||||
</pre></div>
|
||||
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
`[In:]`
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">from</span> <span style="color: #0e84b5; font-weight: bold">platform</span> <span style="color: #008800; font-weight: bold">import</span> python_version
|
||||
<span style="color: #007020">print</span> <span style="background-color: #fff0f0">'This code cell was executed in Python'</span>, python_version()
|
||||
|
||||
i <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">1</span>
|
||||
<span style="color: #007020">print</span> [i <span style="color: #008800; font-weight: bold">for</span> i <span style="color: #000000; font-weight: bold">in</span> <span style="color: #007020">range</span>(<span style="color: #0000DD; font-weight: bold">5</span>)]
|
||||
<span style="color: #007020">print</span> i, <span style="background-color: #fff0f0">'-> i in global'</span>
|
||||
</pre></div>
|
||||
|
||||
<br>
|
||||
`[Out:]`
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">This code cell was executed in Python 2.7.6
|
||||
[0, 1, 2, 3, 4]
|
||||
4 -> i in global
|
||||
</pre></div>
|
||||
|
||||
|
||||
<a id='compare_unorder'></a>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
#### Python 3.x prevents us from comparing unorderable types
|
||||
|
||||
[[back to Python 2.x vs 3.x overview](#py23_overview)]
|
||||
|
||||
<br>
|
||||
`[In:]`
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">from</span> <span style="color: #0e84b5; font-weight: bold">platform</span> <span style="color: #008800; font-weight: bold">import</span> python_version
|
||||
<span style="color: #007020">print</span> <span style="background-color: #fff0f0">'This code cell was executed in Python'</span>, python_version()
|
||||
|
||||
<span style="color: #007020">print</span> [<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>] <span style="color: #333333">></span> <span style="background-color: #fff0f0">'foo'</span>
|
||||
<span style="color: #007020">print</span> (<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>) <span style="color: #333333">></span> <span style="background-color: #fff0f0">'foo'</span>
|
||||
<span style="color: #007020">print</span> [<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>] <span style="color: #333333">></span> (<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>)
|
||||
</pre></div>
|
||||
|
||||
<br>
|
||||
`[Out:]`
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">This code cell was executed in Python 2.7.6
|
||||
False
|
||||
True
|
||||
False
|
||||
</pre></div>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
`[In:]`
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">from</span> <span style="color: #0e84b5; font-weight: bold">platform</span> <span style="color: #008800; font-weight: bold">import</span> python_version
|
||||
<span style="color: #007020">print</span>(<span style="background-color: #fff0f0">'This code cell was executed in Python'</span>, python_version())
|
||||
|
||||
<span style="color: #007020">print</span>([<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>] <span style="color: #333333">></span> <span style="background-color: #fff0f0">'foo'</span>)
|
||||
<span style="color: #007020">print</span>((<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>) <span style="color: #333333">></span> <span style="background-color: #fff0f0">'foo'</span>)
|
||||
<span style="color: #007020">print</span>([<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>] <span style="color: #333333">></span> (<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>))
|
||||
</pre></div>
|
||||
|
||||
`[Out:]`
|
||||
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">This code cell was executed <span style="color: #000000; font-weight: bold">in</span> Python <span style="color: #6600EE; font-weight: bold">3.3</span><span style="color: #333333">.</span><span style="color: #0000DD; font-weight: bold">5</span>
|
||||
<span style="color: #333333">---------------------------------------------------------------------------</span>
|
||||
<span style="color: #FF0000; font-weight: bold">TypeError</span> Traceback (most recent call last)
|
||||
<span style="color: #333333"><</span>ipython<span style="color: #333333">-</span><span style="color: #007020">input</span><span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">3</span><span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">1</span>d774c677f73<span style="color: #333333">></span> <span style="color: #000000; font-weight: bold">in</span> <span style="color: #333333"><</span>module<span style="color: #333333">></span>()
|
||||
<span style="color: #0000DD; font-weight: bold">2</span> <span style="color: #007020">print</span>(<span style="background-color: #fff0f0">'This code cell was executed in Python'</span>, python_version())
|
||||
<span style="color: #0000DD; font-weight: bold">3</span>
|
||||
<span style="color: #333333">----></span> <span style="color: #0000DD; font-weight: bold">4</span> [<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>] <span style="color: #333333">></span> <span style="background-color: #fff0f0">'foo'</span>
|
||||
<span style="color: #0000DD; font-weight: bold">5</span> (<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>) <span style="color: #333333">></span> <span style="background-color: #fff0f0">'foo'</span>
|
||||
<span style="color: #0000DD; font-weight: bold">6</span> [<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>] <span style="color: #333333">></span> (<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>)
|
||||
|
||||
<span style="color: #FF0000; font-weight: bold">TypeError</span>: unorderable types: <span style="color: #007020">list</span>() <span style="color: #333333">></span> <span style="color: #007020">str</span>()
|
||||
</pre></div>
|
Loading…
Reference in New Issue
Block a user