Mercurial > python-for-js-programmers
changeset 40:741b0e6cd9ac
Moved some sections around.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Fri, 06 Jun 2008 13:15:22 -0700 |
parents | b3fdf83125c2 |
children | af7d50fc8cfd |
files | PythonForJsProgrammers.html PythonForJsProgrammers.txt |
diffstat | 2 files changed, 328 insertions(+), 277 deletions(-) [+] |
line wrap: on
line diff
--- a/PythonForJsProgrammers.html Fri Jun 06 12:54:07 2008 -0700 +++ b/PythonForJsProgrammers.html Fri Jun 06 13:15:22 2008 -0700 @@ -52,10 +52,10 @@ something it should already be able to infer from the use of whitespace?</p> <p>This is actually a violation of the <a class="reference" href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">Don't Repeat Yourself</a> (DRY) -principle popularized by Andy Hunt and Dave Thomas. Because unneeded -extra work is required when moving from a single-line clause to a +principle popularized by Andy Hunt and Dave Thomas. Because extra +work is required when moving from a single-line clause to a multiple-line clause, it's a constant source of errors in C-like -languages, and many stylistic rules and arguments have been spawned as +languages, and stylistic rules and arguments have been spawned as a result of this mistake in language design.</p> <p>Python is one of the few languages that takes the simpler and more humane approach: whitespace has a consistent semantic meaning to the @@ -110,7 +110,8 @@ <p>If there's a function you're interested in learning more about, you can look at the built-in documentation metadata associated with the object--known as the <cite>docstring</cite>--by querying the object's <tt class="docutils literal"><span class="pre">__doc__</span></tt> -attribute:</p> +attribute. For instance, here's how to get help on the string +object's <tt class="docutils literal"><span class="pre">join()</span></tt> method:</p> <blockquote> <pre class="doctest-block"> >>> print "a string".join.__doc__ @@ -120,8 +121,7 @@ sequence. The separator between elements is S. </pre> </blockquote> -<p>This makes it very easy and fun to explore the language and its -environs.</p> +<p>This makes it easy and fun to explore the language and its environs.</p> </div> <div class="section"> <h1><a id="batteries-included" name="batteries-included">Batteries Included</a></h1> @@ -152,59 +152,28 @@ </div> <div class="section"> <h1><a id="strings" name="strings">Strings</a></h1> -<p>Strings are, unfortunately, the bane of Python programming. Unlike -JavaScript, in which every string is unicode, strings in Python are -really more like immutable arrays of bytes. Unicode strings are an -entirely different type, and unicode literals must be prepended with a -<tt class="docutils literal"><span class="pre">u</span></tt>, like so:</p> +<p>Strings in Python work a lot like they do in JavaScript, but with some +added benefits.</p> +<p>Strings--or any sequence-like object in Python, for that matter--can +be indexed by character like they can in JavaScript, with the addition +that negative indexes may be used to denote items from the end of the +sequence:</p> <blockquote> <pre class="doctest-block"> ->>> u"I am a unicode string." -u'I am a unicode string.' ->>> "I am a non-unicode string." -'I am a non-unicode string.' -</pre> -</blockquote> -<p>The non-intuitiveness of this is due to historical reasons: Python is -an older language than JavaScript and dates back to 1991, so the -language didn't originally support unicode. When support was added, -it was added in a way that didn't break backwards compatibility. This -situation will be resolved in <a class="reference" href="http://www.python.org/dev/peps/pep-3000/">Python 3000</a>, the first version of -Python to break backwards compatibility with previous versions.</p> -<p>A string with a character encoding may be converted to a <tt class="docutils literal"><span class="pre">unicode</span></tt> -object through the <tt class="docutils literal"><span class="pre">decode()</span></tt> method, like so:</p> -<blockquote> -<pre class="doctest-block"> ->>> "Here is an ellipsis: \xe2\x80\xa6".decode("utf-8") -u'Here is an ellipsis: \u2026' +>>> "Hello"[-1] +'o' </pre> </blockquote> -<p>Conversely, you can convert a <tt class="docutils literal"><span class="pre">unicode</span></tt> object into a string via the -<tt class="docutils literal"><span class="pre">encode()</span></tt> method:</p> -<blockquote> -<pre class="doctest-block"> ->>> u"Here is an ellipsis: \u2026".encode("utf-8") -'Here is an ellipsis: \xe2\x80\xa6' -</pre> -</blockquote> -<p>An exception will be raised if there are characters that aren't -supported by the encoding you specify, though:</p> +<p>Any indexable item can generally also be sliced; this is similar to +<tt class="docutils literal"><span class="pre">String.slice</span></tt> in JavaScript, only built-in to the language:</p> <blockquote> <pre class="doctest-block"> ->>> u"hello\u2026".encode("ascii") -Traceback (most recent call last): -... -UnicodeEncodeError: 'ascii' codec can't encode character u'\u2026' in position 5: ordinal not in range(128) -</pre> -</blockquote> -<p>As such, it's a good idea to optionally specify an algorithm to deal -with characters that aren't supported by the encoding:</p> -<blockquote> -<pre class="doctest-block"> ->>> u"hello\u2026".encode("ascii", "ignore") -'hello' ->>> u"hello\u2026".encode("ascii", "xmlcharrefreplace") -'hello&#8230;' +>>> "hello"[2:4] # Just like "hello".slice(2,4) in JS +'ll' +>>> "hello"[2:] # Just like "hello".slice(2) in JS +'llo' +>>> "hello"[:4] # Just like "hello".slice(0,4) in JS +'hell' </pre> </blockquote> <p>It's also easy to format strings in Python. If you're familiar with @@ -355,7 +324,7 @@ forth.</p> </div> <div class="section"> -<h1><a id="global-variables" name="global-variables">Global Variables</a></h1> +<h1><a id="variables" name="variables">Variables</a></h1> <p>Python, like JavaScript, is lexically scoped when it comes to reading variables.</p> <p>However, Python's scoping rules for assignment to undefined variables @@ -385,41 +354,6 @@ explicitly told otherwise.</p> </div> <div class="section"> -<h1><a id="closures" name="closures">Closures</a></h1> -<p>Function closures are available in Python:</p> -<blockquote> -<pre class="doctest-block"> ->>> def myfunc(): -... a = 1 -... def wrapped(): -... return a -... return wrapped ->>> myfunc()() -1 -</pre> -</blockquote> -<p>Unlike Javascript, however, the variable bindings in the closure are -"read-only":</p> -<blockquote> -<pre class="doctest-block"> ->>> def myfunc(): -... a = 1 -... def wrapped(): -... a += 1 # Doesn't work! -... return a -... return wrapped ->>> myfunc()() -Traceback (most recent call last): -... -UnboundLocalError: local variable 'a' referenced before assignment -</pre> -</blockquote> -<p>This means that closures can't be used to access private variables -like they can in JavaScript; instead, everything is visible, and -implementation-specific variables are conventionally preceded with one -or two underscores.</p> -</div> -<div class="section"> <h1><a id="sequences" name="sequences">Sequences</a></h1> <p>Lists are a lot like JavaScript arrays:</p> <blockquote> @@ -475,6 +409,28 @@ [1, 3] </pre> </blockquote> +<p>It's also possible to index and slice lists and tuples, just like you +can with strings:</p> +<blockquote> +<pre class="doctest-block"> +>>> ["hello", "there", "dude"][-1] +'dude' +</pre> +<pre class="doctest-block"> +>>> [1, 2, 3][1:2] +[2] +</pre> +</blockquote> +<p>In fact, if the datatype is mutable like lists are, you can even +<cite>assign</cite> to slices:</p> +<blockquote> +<pre class="doctest-block"> +>>> a = [1, 2, 3, 4] +>>> a[1:3] = [5] +>>> a +[1, 5, 4] +</pre> +</blockquote> </div> <div class="section"> <h1><a id="control-flow" name="control-flow">Control Flow</a></h1> @@ -513,41 +469,6 @@ </blockquote> </div> <div class="section"> -<h1><a id="indexing-and-slicing" name="indexing-and-slicing">Indexing and Slicing</a></h1> -<p>Any item that is a sequence can be indexed as expected, but unlike -Javascript, negative indexes may be used to denote items from the end -of the sequence:</p> -<blockquote> -<pre class="doctest-block"> ->>> ["hello", "there", "dude"][-1] -'dude' -</pre> -</blockquote> -<p>Any indexable item can generally also be sliced; this is similar to -<tt class="docutils literal"><span class="pre">String.slice</span></tt> in JavaScript, only built-in to the language:</p> -<blockquote> -<pre class="doctest-block"> ->>> "hello"[2:4] # Just like "hello".slice(2,4) in JS -'ll' ->>> "hello"[2:] # Just like "hello".slice(2) in JS -'llo' ->>> "hello"[:4] # Just like "hello".slice(0,4) in JS -'hell' ->>> [1, 2, 3][1:2] # Works on lists, too! -[2] -</pre> -</blockquote> -<p>If the datatype is mutable, you can even assign to slices:</p> -<blockquote> -<pre class="doctest-block"> ->>> a = [1, 2, 3, 4] ->>> a[1:3] = [5] ->>> a -[1, 5, 4] -</pre> -</blockquote> -</div> -<div class="section"> <h1><a id="dictionaries" name="dictionaries">Dictionaries</a></h1> <p>Dictionaries are a bit like Object literals in JavaScript:</p> <blockquote> @@ -658,31 +579,7 @@ <p>As you can see, classes in Python aren't particularly elegant; it's hard to understand exactly <cite>why</cite> things work the way they do unless you understand how classes are implemented "under the hood", which is -unfortunate. There are also some bumps in the history of Python's -class mechanism: until version 2.2, Python's built-in types weren't -part of the class heirarchy, and there was no root <tt class="docutils literal"><span class="pre">object</span></tt> class; -these kinds of classes were known as <cite>old-style classes</cite>, and are -being mentioned here solely because you may run across them when -reading old code. They don't support a lot of the things that -new-style classes do, and should be avoided if at all possible. You -can tell that an object is an instance of an old-style or new-style -class by using the <tt class="docutils literal"><span class="pre">type</span></tt> built-in function:</p> -<blockquote> -<pre class="doctest-block"> ->>> class OldStyle: # No superclass means it's old-style. -... pass ->>> class NewStyle(object): -... pass ->>> type(OldStyle()) -<type 'instance'> ->>> type(NewStyle()) -<class 'NewStyle'> -</pre> -</blockquote> -<p>A number of the class mechanisms outlined in this tutorial don't work -with old-style classes. Fortunately, as with the string/unicode -schism, this confusion will be resolved in Python 3000, which abandons -old-style classes to their well-deserved fate.</p> +unfortunate.</p> <p>Because classes in Python aren't really prototype-based, it's not easy to dynamically add or remove methods to existing objects on-the-fly--though some will probably tell you that doing such a thing @@ -779,6 +676,41 @@ </blockquote> </div> <div class="section"> +<h1><a id="closures" name="closures">Closures</a></h1> +<p>Function closures are available in Python:</p> +<blockquote> +<pre class="doctest-block"> +>>> def myfunc(): +... a = 1 +... def wrapped(): +... return a +... return wrapped +>>> myfunc()() +1 +</pre> +</blockquote> +<p>Unlike Javascript, however, the variable bindings in the closure are +"read-only":</p> +<blockquote> +<pre class="doctest-block"> +>>> def myfunc(): +... a = 1 +... def wrapped(): +... a += 1 # Doesn't work! +... return a +... return wrapped +>>> myfunc()() +Traceback (most recent call last): +... +UnboundLocalError: local variable 'a' referenced before assignment +</pre> +</blockquote> +<p>This means that closures can't be used to access private variables +like they can in JavaScript; instead, everything is visible, and +implementation-specific variables are conventionally preceded with one +or two underscores.</p> +</div> +<div class="section"> <h1><a id="borrowed-goods" name="borrowed-goods">Borrowed Goods</a></h1> <p>As mentioned at the beginning of this document, some of JavaScript's latest features have been borrowed directly from Python.</p> @@ -787,6 +719,99 @@ 1.7 <a class="reference" href="http://wiki.ecmascript.org/doku.php?id=proposals:iterators_and_generators">counterparts</a>.</p> </div> <div class="section"> +<h1><a id="caveats" name="caveats">Caveats</a></h1> +<p>As with any language, there's a few wrinkles in Python's design and +history that any newcomer should be aware of. I'll try to outline the +most important ones below.</p> +<div class="section"> +<h2><a id="unicode" name="unicode">Unicode</a></h2> +<p>Sometimes, strings are the bane of Python programming. Unlike +JavaScript, in which every string is unicode, strings in Python are +really more like immutable arrays of bytes. Unicode strings are an +entirely different type, and unicode literals must be prepended with a +<tt class="docutils literal"><span class="pre">u</span></tt>, like so:</p> +<blockquote> +<pre class="doctest-block"> +>>> u"I am a unicode string." +u'I am a unicode string.' +>>> "I am a non-unicode string." +'I am a non-unicode string.' +</pre> +</blockquote> +<p>The non-intuitiveness of this is due to historical reasons: Python is +an older language than JavaScript and dates back to 1991, so the +language didn't originally support unicode. When support was added, +it was added in a way that didn't break backwards compatibility. This +situation will be resolved in <a class="reference" href="http://www.python.org/dev/peps/pep-3000/">Python 3000</a>, the first version of +Python to break backwards compatibility with previous versions.</p> +<p>A string with a character encoding may be converted to a <tt class="docutils literal"><span class="pre">unicode</span></tt> +object through the <tt class="docutils literal"><span class="pre">decode()</span></tt> method, like so:</p> +<blockquote> +<pre class="doctest-block"> +>>> "Here is an ellipsis: \xe2\x80\xa6".decode("utf-8") +u'Here is an ellipsis: \u2026' +</pre> +</blockquote> +<p>Conversely, you can convert a <tt class="docutils literal"><span class="pre">unicode</span></tt> object into a string via the +<tt class="docutils literal"><span class="pre">encode()</span></tt> method:</p> +<blockquote> +<pre class="doctest-block"> +>>> u"Here is an ellipsis: \u2026".encode("utf-8") +'Here is an ellipsis: \xe2\x80\xa6' +</pre> +</blockquote> +<p>An exception will be raised if there are characters that aren't +supported by the encoding you specify, though:</p> +<blockquote> +<pre class="doctest-block"> +>>> u"hello\u2026".encode("ascii") +Traceback (most recent call last): +... +UnicodeEncodeError: 'ascii' codec can't encode character u'\u2026' in position 5: ordinal not in range(128) +</pre> +</blockquote> +<p>As such, it's a good idea to optionally specify an algorithm to deal +with characters that aren't supported by the encoding:</p> +<blockquote> +<pre class="doctest-block"> +>>> u"hello\u2026".encode("ascii", "ignore") +'hello' +>>> u"hello\u2026".encode("ascii", "xmlcharrefreplace") +'hello&#8230;' +</pre> +</blockquote> +</div> +<div class="section"> +<h2><a id="old-style-classes" name="old-style-classes">Old-Style Classes</a></h2> +<p>There are also some bumps in the history of Python's +class mechanism: until version 2.2, Python's built-in types weren't +part of the class heirarchy, and there was no root <tt class="docutils literal"><span class="pre">object</span></tt> class; +these kinds of classes were known as <cite>old-style classes</cite>, and are +being mentioned here solely because you may run across them when +reading old code. They don't support a lot of the things that +new-style classes do, and should be avoided if at all possible. You +can tell that an object is an instance of an old-style or new-style +class by using the <tt class="docutils literal"><span class="pre">type</span></tt> built-in function:</p> +<blockquote> +<pre class="doctest-block"> +>>> class OldStyle: # No superclass means it's old-style. +... pass +>>> class NewStyle(object): +... pass +>>> type(OldStyle()) +<type 'instance'> +>>> type(NewStyle()) +<class 'NewStyle'> +</pre> +</blockquote> +<p>A number of the class mechanisms outlined in this tutorial, such as +the <tt class="docutils literal"><span class="pre">property()</span></tt> and <tt class="docutils literal"><span class="pre">super()</span></tt> built-in functions, don't work with +old-style classes. Fortunately, as with the string/unicode schism, +this confusion will be resolved in Python 3000, which abandons +old-style classes to their well-deserved fate.</p> +</div> +</div> +<div class="section"> <h1><a id="coding-style" name="coding-style">Coding Style</a></h1> <p>Python has a coding convention that's generally been embraced throughout the community; almost all libraries use it. It's contained
--- a/PythonForJsProgrammers.txt Fri Jun 06 12:54:07 2008 -0700 +++ b/PythonForJsProgrammers.txt Fri Jun 06 13:15:22 2008 -0700 @@ -154,51 +154,26 @@ Strings ======= -Strings are, unfortunately, the bane of Python programming. Unlike -JavaScript, in which every string is unicode, strings in Python are -really more like immutable arrays of bytes. Unicode strings are an -entirely different type, and unicode literals must be prepended with a -``u``, like so: +Strings in Python work a lot like they do in JavaScript, but with some +added benefits. - >>> u"I am a unicode string." - u'I am a unicode string.' - >>> "I am a non-unicode string." - 'I am a non-unicode string.' - -The non-intuitiveness of this is due to historical reasons: Python is -an older language than JavaScript and dates back to 1991, so the -language didn't originally support unicode. When support was added, -it was added in a way that didn't break backwards compatibility. This -situation will be resolved in `Python 3000`_, the first version of -Python to break backwards compatibility with previous versions. - -A string with a character encoding may be converted to a ``unicode`` -object through the ``decode()`` method, like so: +Strings--or any sequence-like object in Python, for that matter--can +be indexed by character like they can in JavaScript, with the addition +that negative indexes may be used to denote items from the end of the +sequence: - >>> "Here is an ellipsis: \xe2\x80\xa6".decode("utf-8") - u'Here is an ellipsis: \u2026' - -Conversely, you can convert a ``unicode`` object into a string via the -``encode()`` method: + >>> "Hello"[-1] + 'o' - >>> u"Here is an ellipsis: \u2026".encode("utf-8") - 'Here is an ellipsis: \xe2\x80\xa6' - -An exception will be raised if there are characters that aren't -supported by the encoding you specify, though: +Any indexable item can generally also be sliced; this is similar to +``String.slice`` in JavaScript, only built-in to the language: - >>> u"hello\u2026".encode("ascii") - Traceback (most recent call last): - ... - UnicodeEncodeError: 'ascii' codec can't encode character u'\u2026' in position 5: ordinal not in range(128) - -As such, it's a good idea to optionally specify an algorithm to deal -with characters that aren't supported by the encoding: - - >>> u"hello\u2026".encode("ascii", "ignore") - 'hello' - >>> u"hello\u2026".encode("ascii", "xmlcharrefreplace") - 'hello…' + >>> "hello"[2:4] # Just like "hello".slice(2,4) in JS + 'll' + >>> "hello"[2:] # Just like "hello".slice(2) in JS + 'llo' + >>> "hello"[:4] # Just like "hello".slice(0,4) in JS + 'hell' It's also easy to format strings in Python. If you're familiar with C's ``sprintf()`` function, Python's string interpolation operator, @@ -210,7 +185,6 @@ You can find out more in the `String Formatting Operations`_ section of the Python Library Reference. -.. _`Python 3000`: http://www.python.org/dev/peps/pep-3000/ .. _`String Formatting Operations`: http://docs.python.org/lib/typesseq-strings.html Expressions @@ -332,8 +306,8 @@ .. _`arbitrary argument lists`: http://docs.python.org/tut/node6.html#SECTION006730000000000000000 -Global Variables -================ +Variables +========= Python, like JavaScript, is lexically scoped when it comes to reading variables. @@ -362,38 +336,6 @@ interpreter to assume that all new assignments are local unless explicitly told otherwise. -Closures -======== - -Function closures are available in Python: - - >>> def myfunc(): - ... a = 1 - ... def wrapped(): - ... return a - ... return wrapped - >>> myfunc()() - 1 - -Unlike Javascript, however, the variable bindings in the closure are -"read-only": - - >>> def myfunc(): - ... a = 1 - ... def wrapped(): - ... a += 1 # Doesn't work! - ... return a - ... return wrapped - >>> myfunc()() - Traceback (most recent call last): - ... - UnboundLocalError: local variable 'a' referenced before assignment - -This means that closures can't be used to access private variables -like they can in JavaScript; instead, everything is visible, and -implementation-specific variables are conventionally preceded with one -or two underscores. - Sequences ========= @@ -439,6 +381,23 @@ >>> a [1, 3] +It's also possible to index and slice lists and tuples, just like you +can with strings: + + >>> ["hello", "there", "dude"][-1] + 'dude' + + >>> [1, 2, 3][1:2] + [2] + +In fact, if the datatype is mutable like lists are, you can even +`assign` to slices: + + >>> a = [1, 2, 3, 4] + >>> a[1:3] = [5] + >>> a + [1, 5, 4] + Control Flow ============ @@ -470,35 +429,6 @@ 1 2 -Indexing and Slicing -==================== - -Any item that is a sequence can be indexed as expected, but unlike -Javascript, negative indexes may be used to denote items from the end -of the sequence: - - >>> ["hello", "there", "dude"][-1] - 'dude' - -Any indexable item can generally also be sliced; this is similar to -``String.slice`` in JavaScript, only built-in to the language: - - >>> "hello"[2:4] # Just like "hello".slice(2,4) in JS - 'll' - >>> "hello"[2:] # Just like "hello".slice(2) in JS - 'llo' - >>> "hello"[:4] # Just like "hello".slice(0,4) in JS - 'hell' - >>> [1, 2, 3][1:2] # Works on lists, too! - [2] - -If the datatype is mutable, you can even assign to slices: - - >>> a = [1, 2, 3, 4] - >>> a[1:3] = [5] - >>> a - [1, 5, 4] - Dictionaries ============ @@ -594,29 +524,7 @@ As you can see, classes in Python aren't particularly elegant; it's hard to understand exactly `why` things work the way they do unless you understand how classes are implemented "under the hood", which is -unfortunate. There are also some bumps in the history of Python's -class mechanism: until version 2.2, Python's built-in types weren't -part of the class heirarchy, and there was no root ``object`` class; -these kinds of classes were known as `old-style classes`, and are -being mentioned here solely because you may run across them when -reading old code. They don't support a lot of the things that -new-style classes do, and should be avoided if at all possible. You -can tell that an object is an instance of an old-style or new-style -class by using the ``type`` built-in function: - - >>> class OldStyle: # No superclass means it's old-style. - ... pass - >>> class NewStyle(object): - ... pass - >>> type(OldStyle()) - <type 'instance'> - >>> type(NewStyle()) - <class 'NewStyle'> - -A number of the class mechanisms outlined in this tutorial don't work -with old-style classes. Fortunately, as with the string/unicode -schism, this confusion will be resolved in Python 3000, which abandons -old-style classes to their well-deserved fate. +unfortunate. Because classes in Python aren't really prototype-based, it's not easy to dynamically add or remove methods to existing objects @@ -709,6 +617,38 @@ .. _`built-in ones`: http://docs.python.org/lib/module-exceptions.html +Closures +======== + +Function closures are available in Python: + + >>> def myfunc(): + ... a = 1 + ... def wrapped(): + ... return a + ... return wrapped + >>> myfunc()() + 1 + +Unlike Javascript, however, the variable bindings in the closure are +"read-only": + + >>> def myfunc(): + ... a = 1 + ... def wrapped(): + ... a += 1 # Doesn't work! + ... return a + ... return wrapped + >>> myfunc()() + Traceback (most recent call last): + ... + UnboundLocalError: local variable 'a' referenced before assignment + +This means that closures can't be used to access private variables +like they can in JavaScript; instead, everything is visible, and +implementation-specific variables are conventionally preceded with one +or two underscores. + Borrowed Goods ============== @@ -725,6 +665,92 @@ .. _`list comprehensions`: http://docs.python.org/tut/node7.html#SECTION007140000000000000000 .. _`counterparts`: http://wiki.ecmascript.org/doku.php?id=proposals:iterators_and_generators +Caveats +======= + +As with any language, there's a few wrinkles in Python's design and +history that any newcomer should be aware of. I'll try to outline the +most important ones below. + +Unicode +------- + +Sometimes, strings are the bane of Python programming. Unlike +JavaScript, in which every string is unicode, strings in Python are +really more like immutable arrays of bytes. Unicode strings are an +entirely different type, and unicode literals must be prepended with a +``u``, like so: + + >>> u"I am a unicode string." + u'I am a unicode string.' + >>> "I am a non-unicode string." + 'I am a non-unicode string.' + +The non-intuitiveness of this is due to historical reasons: Python is +an older language than JavaScript and dates back to 1991, so the +language didn't originally support unicode. When support was added, +it was added in a way that didn't break backwards compatibility. This +situation will be resolved in `Python 3000`_, the first version of +Python to break backwards compatibility with previous versions. + +A string with a character encoding may be converted to a ``unicode`` +object through the ``decode()`` method, like so: + + >>> "Here is an ellipsis: \xe2\x80\xa6".decode("utf-8") + u'Here is an ellipsis: \u2026' + +Conversely, you can convert a ``unicode`` object into a string via the +``encode()`` method: + + >>> u"Here is an ellipsis: \u2026".encode("utf-8") + 'Here is an ellipsis: \xe2\x80\xa6' + +An exception will be raised if there are characters that aren't +supported by the encoding you specify, though: + + >>> u"hello\u2026".encode("ascii") + Traceback (most recent call last): + ... + UnicodeEncodeError: 'ascii' codec can't encode character u'\u2026' in position 5: ordinal not in range(128) + +As such, it's a good idea to optionally specify an algorithm to deal +with characters that aren't supported by the encoding: + + >>> u"hello\u2026".encode("ascii", "ignore") + 'hello' + >>> u"hello\u2026".encode("ascii", "xmlcharrefreplace") + 'hello…' + +.. _`Python 3000`: http://www.python.org/dev/peps/pep-3000/ + +Old-Style Classes +----------------- + +There are also some bumps in the history of Python's +class mechanism: until version 2.2, Python's built-in types weren't +part of the class heirarchy, and there was no root ``object`` class; +these kinds of classes were known as `old-style classes`, and are +being mentioned here solely because you may run across them when +reading old code. They don't support a lot of the things that +new-style classes do, and should be avoided if at all possible. You +can tell that an object is an instance of an old-style or new-style +class by using the ``type`` built-in function: + + >>> class OldStyle: # No superclass means it's old-style. + ... pass + >>> class NewStyle(object): + ... pass + >>> type(OldStyle()) + <type 'instance'> + >>> type(NewStyle()) + <class 'NewStyle'> + +A number of the class mechanisms outlined in this tutorial, such as +the ``property()`` and ``super()`` built-in functions, don't work with +old-style classes. Fortunately, as with the string/unicode schism, +this confusion will be resolved in Python 3000, which abandons +old-style classes to their well-deserved fate. + Coding Style ============