Mercurial > python-for-js-programmers
changeset 35:3179304015bf
Added auto-generated HTML file, so it can be viewed over hgweb.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Fri, 06 Jun 2008 06:32:56 -0700 |
parents | 1e3903e6968a |
children | f1e8805a9666 |
files | PythonForJsProgrammers.html |
diffstat | 1 files changed, 703 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PythonForJsProgrammers.html Fri Jun 06 06:32:56 2008 -0700 @@ -0,0 +1,703 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" /> +<title>Python for JavaScript Programmers</title> +<link rel="stylesheet" href="PythonForJsProgrammers.css" type="text/css" /> +</head> +<body> +<div class="document" id="python-for-javascript-programmers"> +<h1 class="title">Python for JavaScript Programmers</h1> +<p>By Atul Varma</p> +<p>I couldn't find anything on the web that attempted to teach Python to +readers who already knew JavaScript, so I thought I'd give it a shot, +since a number of my friends at Mozilla don't know much about Python +but know JavaScript incredibly well. The languages actually aren't +that dissimilar--in fact, some of JavaScript's latest features have +been <a class="reference" href="http://weblogs.mozillazine.org/roadmap/archives/2006/02/js_and_python_news.html">borrowed directly from Python</a>.</p> +<div class="section"> +<h1><a id="whitespace" name="whitespace">Whitespace</a></h1> +<p>This is a good time to explain a bit about Python's design philosophy; +hopefully it will give you a better idea of whether this is a language +you'd like to use.</p> +<p>While not syntactically enforced by many languages, whitespace is +semantically meaningful during the reading and writing of code. Take +the following example of C-like code:</p> +<pre class="literal-block"> +if (someVar == 1) + doSomething(); +</pre> +<p>The line <tt class="docutils literal"><span class="pre">doSomething();</span></tt> is indented after the <tt class="docutils literal"><span class="pre">if</span></tt> statement to +indicate that it should only be done if the statement above it is +true. Given this, consider what the following code does:</p> +<pre class="literal-block"> +if (someVar == 1) + doSomething(); + doSomethingElse(); +</pre> +<p>It's clear from the use of whitespace that <tt class="docutils literal"><span class="pre">doSomethingElse();</span></tt> +should also only be executed if the statement it's indented under is +true, but this is not the case for C-like languages. Indeed, the +programmer must add additional code to tell the compiler what he or +she means:</p> +<pre class="literal-block"> +if (someVar == 1) { + doSomething(); + doSomethingElse(); +} +</pre> +<p>Why does the programmer have to write more code to tell the computer +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 +multiple-line clause, it's a constant source of errors in C-like +languages, and many 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 +humans who write code, so the computer should take this into account +when it processes the code. This reduces the burden on the programmer +from having to repeat their intent in multiple different ways.</p> +<p>So, you won't see any brackets in Python. Instead, if a statement +ends with a colon, the next statement needs to be indented and begins +a new block. The block ends as soon as an unindented line is +encountered, like so:</p> +<pre class="literal-block"> +if someVar == 1: + doSomething() + doSomethingElse() +else: + doOtherThing() +</pre> +<p>Also note that Python doesn't use semicolons, which is yet another +language feature that reduces the cognitive burden on the programmer. +Indeed, many of the language features covered below were designed with +a very careful eye towards readability, reducing cognitive load, and +making the process of programming <a class="reference" href="http://xkcd.com/353/">as enjoyable as possible</a>.</p> +</div> +<div class="section"> +<h1><a id="the-interactive-shell" name="the-interactive-shell">The Interactive Shell</a></h1> +<p>Python, when executed with no parameters, just presents an interactive +interpreter. It's similar to the SpiderMonkey/Rhino shell and +<tt class="docutils literal"><span class="pre">xpcshell</span></tt> if you're familiar with those. All following code examples +in this tutorial will be displayed as though they're being executed in +it, like so:</p> +<blockquote> +<pre class="doctest-block"> +>>> 1 + 2 +3 +>>> # Here's a comment that does nothing. +>>> print "hi!" +hi! +>>> print "This is a long " \ +... "statement that spans multiple lines." +This is a long statement that spans multiple lines. +</pre> +</blockquote> +<p>One built-in function in particular that helps explore things in the +built-in shell is <tt class="docutils literal"><span class="pre">dir()</span></tt>, which returns a list of all the +attributes attached to an object:</p> +<blockquote> +<pre class="doctest-block"> +>>> dir("a string") +['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__str__', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] +</pre> +</blockquote> +<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> +<blockquote> +<pre class="doctest-block"> +>>> print "a string".join.__doc__ +S.join(sequence) -> string +<BLANKLINE> +Return a string which is the concatenation of the strings in the +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> +</div> +<div class="section"> +<h1><a id="batteries-included" name="batteries-included">Batteries Included</a></h1> +<p>Python comes with a standard library that provides a great deal of +functionality, from enhanced introspection to serialization, logging, +XML processing, database access, testing, networking, data archiving, +and more. Extensive documentation for it all is contained in the +<a class="reference" href="http://docs.python.org/lib/lib.html">Python Library Reference</a>.</p> +<p>To use the functionality of a module, you'll use Python's <tt class="docutils literal"><span class="pre">import</span></tt> +statement, like so:</p> +<blockquote> +<pre class="doctest-block"> +>>> import sha +</pre> +</blockquote> +<p>This particular line imports the <a class="reference" href="http://docs.python.org/lib/module-sha.html">sha</a> module, which provides access +to the SHA-1 message digest algorithm. At this point, <tt class="docutils literal"><span class="pre">sha</span></tt> is an +object in your namespace and can be used, for instance, to create a +<tt class="docutils literal"><span class="pre">sha</span></tt> object from which to generate a hex digest:</p> +<blockquote> +<pre class="doctest-block"> +>>> sha.sha("hello").hexdigest() +'aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d' +</pre> +</blockquote> +<p>It's not hard to create your own modules; you can learn how to do it +in the <a class="reference" href="http://docs.python.org/tut/node8.html">Modules</a> section of the official Python Tutorial.</p> +</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> +<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"> +<h1><a id="expressions" name="expressions">Expressions</a></h1> +<p>Python's expression syntax is much like that of JavaScript, or any +C-like language for that matter:</p> +<blockquote> +<pre class="doctest-block"> +>>> 9 & 1 # Bitwise operations +1 +>>> 2 << 2 # Shifting +8 +>>> 5 >= 3 # Comparisons +True +>>> 8 + 2 * (3 + 5) # Arithmetic +24 +>>> 1 == 1 # Equivalence +True +</pre> +</blockquote> +<p>Some C-like expression constructs have been substituted for more +readable alternatives:</p> +<blockquote> +<pre class="doctest-block"> +>>> not True # 'not' instead of '!' +False +>>> True and True # 'and' instead of '&&' +True +>>> True or False # 'or' instead of '||' +True +</pre> +</blockquote> +<p>But there's some elements of C-like expressions that aren't supported, +because they tend to be more trouble than they're worth. For +instance, some constructs that can be used in expressions in C-like +languages can only be used in statements in Python:</p> +<blockquote> +<pre class="doctest-block"> +>>> a = 5 # Assignment works in statements. +>>> a += 1 # Add-assignment does too. +>>> if a = 1: # But you can't assign in an expression. +... pass +Traceback (most recent call last): +... +SyntaxError: invalid syntax +</pre> +</blockquote> +<p>The <tt class="docutils literal"><span class="pre">++</span></tt> and <tt class="docutils literal"><span class="pre">--</span></tt> unary assignment operators aren't part of the +Python language, and nor is JavaScript's <tt class="docutils literal"><span class="pre">===</span></tt> comparison operator +(Python's <tt class="docutils literal"><span class="pre">==</span></tt> can be considered to behave like JavaScript's +<tt class="docutils literal"><span class="pre">===</span></tt>).</p> +</div> +<div class="section"> +<h1><a id="nothingness" name="nothingness">Nothingness</a></h1> +<p>Unlike JavaScript, Python doesn't have a concept of <tt class="docutils literal"><span class="pre">undefined</span></tt>. +Instead, things that would normally cause <tt class="docutils literal"><span class="pre">undefined</span></tt> to be returned +by JavaScript simply end up raising an exception in Python:</p> +<blockquote> +<pre class="doctest-block"> +>>> "a string".foo +Traceback (most recent call last): +... +AttributeError: 'str' object has no attribute 'foo' +</pre> +</blockquote> +<p>In most cases, this is for the best, as it makes debugging easier. If +you really need to find out if an object has a particular attribute, +however, you can use the <tt class="docutils literal"><span class="pre">hasattr()</span></tt> function:</p> +<blockquote> +<pre class="doctest-block"> +>>> hasattr("a string", "foo") +False +</pre> +</blockquote> +<p>Python also has an analog to JavaScript's <tt class="docutils literal"><span class="pre">null</span></tt>: it's called +<tt class="docutils literal"><span class="pre">None</span></tt>.</p> +</div> +<div class="section"> +<h1><a id="functions" name="functions">Functions</a></h1> +<p>Functions are defined like so:</p> +<blockquote> +<pre class="doctest-block"> +>>> def foo(x): +... print "foo called with parameter: %s" % x +</pre> +</blockquote> +<p>They are called as you'd expect:</p> +<blockquote> +<pre class="doctest-block"> +>>> foo(5) +foo called with parameter: 5 +</pre> +</blockquote> +<p>Unlike JavaScript, though, it's not possible to call them with fewer +or more arguments than they'd expect:</p> +<blockquote> +<pre class="doctest-block"> +>>> foo() +Traceback (most recent call last): +... +TypeError: foo() takes exactly 1 argument (0 given) +</pre> +</blockquote> +<p>Though it is possible to provide defaults for arguments:</p> +<blockquote> +<pre class="doctest-block"> +>>> def bar(x, y=1, z=5): +... return x + y + z +</pre> +</blockquote> +<p>And it's also possible to specify arguments using keywords:</p> +<blockquote> +<pre class="doctest-block"> +>>> bar(1, z=6) +8 +</pre> +</blockquote> +<p>You can also write documentation for functions by providing a string +immediately following the function signature:</p> +<blockquote> +<pre class="doctest-block"> +>>> def foo(): +... "Does something useless" +... pass +</pre> +</blockquote> +<p>As mentioned earlier, this string is called the docstring, and is +actually attached to the function object as its <tt class="docutils literal"><span class="pre">__doc__</span></tt> attribute. +Creating docstrings for your functions not only helps document your +code, but also makes it easier for Python users to interactively +explore your code, too.</p> +<p>As in JavaScript, Functions are first-class citizens and can be passed +around as parameters to other functions and so forth.</p> +</div> +<div class="section"> +<h1><a id="global-variables" name="global-variables">Global 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 +works opposite to JavaScript's; instead of being global by default, +variables are local, and there is no analog to <tt class="docutils literal"><span class="pre">var</span></tt> or <tt class="docutils literal"><span class="pre">let</span></tt>. +Rather, the <tt class="docutils literal"><span class="pre">global</span></tt> keyword is used to specify that a variable be +bound to global instead of local scope:</p> +<blockquote> +<pre class="doctest-block"> +>>> a = 1 # Define our global variable. +>>> def foo(x): +... a = x + 1 # 'a' is a new local variable. +>>> def bar(x): +... global a # Bind 'a' to the global scope. +... a = x + 1 +>>> foo(5) +>>> a +1 +>>> bar(5) +>>> a +6 +</pre> +</blockquote> +<p>This is for the best: as it's well-known that global variables should +be used as sparingly as possible, it's better for a language +interpreter to assume that all new assignments are local unless +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> +<pre class="doctest-block"> +>>> mylist = ["hello", "there"] +</pre> +</blockquote> +<p>Iterating through them is easy:</p> +<blockquote> +<pre class="doctest-block"> +>>> for i in mylist: +... print i +hello +there +</pre> +</blockquote> +<p>Strings are just sequences of characters, so they can be used +similarly:</p> +<blockquote> +<pre class="doctest-block"> +>>> for c in "boof": +... print c +b +o +o +f +</pre> +</blockquote> +<p>Tuples are just like lists, only they're immutable and differentiated +from lists by using parentheses instead of brackets:</p> +<blockquote> +<pre class="doctest-block"> +>>> mytuple = ("hello", "there") +>>> mytuple[0] = "bye" +Traceback (most recent call last): +... +TypeError: 'tuple' object does not support item assignment +</pre> +</blockquote> +<p>Tuples with a single item look a little weird, though:</p> +<blockquote> +<pre class="doctest-block"> +>>> mytuple = ("hello",) # Without the comma, it'd just be a string. +</pre> +</blockquote> +<p>It's also not possible for there to be "holes" in Python lists like +there are in Javascript arrays:</p> +<blockquote> +<pre class="doctest-block"> +>>> a = [1, 2, 3] +>>> del a[1] # Deletes '2' +>>> a +[1, 3] +</pre> +</blockquote> +</div> +<div class="section"> +<h1><a id="control-flow" name="control-flow">Control Flow</a></h1> +<p>You've already seen examples of <tt class="docutils literal"><span class="pre">for</span></tt>, <tt class="docutils literal"><span class="pre">if</span></tt>, and <tt class="docutils literal"><span class="pre">if...else</span></tt>. +Python also supports <tt class="docutils literal"><span class="pre">if...elif</span></tt>:</p> +<blockquote> +<pre class="doctest-block"> +>>> if 1 == 2: +... pass +... elif 1 == 1: +... print "Hooray!" +... else: +... print "Boo." +Hooray! +</pre> +</blockquote> +<p>It also supports <tt class="docutils literal"><span class="pre">while</span></tt>:</p> +<blockquote> +<pre class="doctest-block"> +>>> while False: +... print "This should never display." +</pre> +</blockquote> +<p>However, Python does not have a <tt class="docutils literal"><span class="pre">do...while</span></tt> loop.</p> +<p>To loop through a range of numbers, you can use the <tt class="docutils literal"><span class="pre">range()</span></tt> +built-in function, which returns a list of numbers in the range you +specify:</p> +<blockquote> +<pre class="doctest-block"> +>>> for i in range(3): +... print i +0 +1 +2 +</pre> +</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> +<pre class="doctest-block"> +>>> d = {"foo" : 1, "bar" : 2} +>>> d["foo"] +1 +</pre> +</blockquote> +<p>Their properties can't be referenced using dot notation, though:</p> +<blockquote> +<pre class="doctest-block"> +>>> d.foo +Traceback (most recent call last): +... +AttributeError: 'dict' object has no attribute 'foo' +</pre> +</blockquote> +<p>Dictionaries generally aren't used to create arbitrary objects like +they are in Javascript; they don't have prototypes, nor do they have +meta-methods. Instead, classes are used to do that sort of thing.</p> +</div> +<div class="section"> +<h1><a id="classes" name="classes">Classes</a></h1> +<p>Classes are pretty straightforward:</p> +<blockquote> +<pre class="doctest-block"> +>>> class Foo(object): +... def __init__(self, a): +... self.a = a +... print "Foo created." +... def doThing(self): +... return self.a + 1 +</pre> +</blockquote> +<p>Here <tt class="docutils literal"><span class="pre">Foo</span></tt> is a subclass of <tt class="docutils literal"><span class="pre">object</span></tt>, which is the root object +class that any class should ultimately descend from. The constructor +is always called <tt class="docutils literal"><span class="pre">__init__()</span></tt> and is invoked like so:</p> +<blockquote> +<pre class="doctest-block"> +>>> f = Foo(1) +Foo created. +</pre> +</blockquote> +<p>So you don't need to use a <tt class="docutils literal"><span class="pre">new</span></tt> operator or anything as is the case +with JS. Calling methods and accessing attributes is straightforward +too:</p> +<blockquote> +<pre class="doctest-block"> +>>> f.a +1 +>>> f.doThing() +2 +</pre> +</blockquote> +<p>Classes in Python get inheritance for free, but because they're not +really prototype-based, it's not easy to dynamically add or remove +methods to existing objects on-the-fly.</p> +<p>An object's methods are also bound to the object itself once it's +created; that is, the <tt class="docutils literal"><span class="pre">self</span></tt> parameter that's passed to them is +always the same, unlike the <tt class="docutils literal"><span class="pre">this</span></tt> parameter in JavaScript which +changes based on the object the function is attached to:</p> +<blockquote> +<pre class="doctest-block"> +>>> f = Foo(5) +Foo created. +>>> doThing = f.doThing +>>> doThing() +6 +</pre> +</blockquote> +</div> +<div class="section"> +<h1><a id="properties" name="properties">Properties</a></h1> +<p>You can achieve the equivalent of JavaScript's getters and setters by +creating a <tt class="docutils literal"><span class="pre">property</span></tt> in a class definition:</p> +<blockquote> +<pre class="doctest-block"> +>>> class Foo(object): +... def _get_bar(self): +... print "getting bar!" +... return 5 +... bar = property(fget = _get_bar) +</pre> +</blockquote> +<p>Not quite as elegant as JavaScript's <tt class="docutils literal"><span class="pre">get</span></tt> keyword in an object +initializer, but it gets the job done:</p> +<blockquote> +<pre class="doctest-block"> +>>> f = Foo() +>>> f.bar +getting bar! +5 +</pre> +</blockquote> +<p>Note that since we didn't define a setter, we've effectively created a +read-only attribute:</p> +<blockquote> +<pre class="doctest-block"> +>>> f.bar = 5 +Traceback (most recent call last): +... +AttributeError: can't set attribute +</pre> +</blockquote> +</div> +<div class="section"> +<h1><a id="operator-overloading-and-special-methods" name="operator-overloading-and-special-methods">Operator Overloading and Special Methods</a></h1> +<p>Classes can define methods with special names to do all sorts of +dynamic things, from operator overloading to custom attribute access +and more. You can read about tehm more in the Python Reference +Manual's section on <a class="reference" href="http://docs.python.org/ref/specialnames.html">special method names</a>.</p> +</div> +<div class="section"> +<h1><a id="exceptions" name="exceptions">Exceptions</a></h1> +<p>They work as expected, and there's a number of <a class="reference" href="http://docs.python.org/lib/module-exceptions.html">built-in ones</a>.</p> +<p>Python prefers the term <tt class="docutils literal"><span class="pre">raise</span></tt> to JavaScript's <tt class="docutils literal"><span class="pre">throw</span></tt>, and +<tt class="docutils literal"><span class="pre">except</span></tt> to JavaScript's <tt class="docutils literal"><span class="pre">catch</span></tt>. Given this, the following +code is fairly self-explanatory:</p> +<blockquote> +<pre class="doctest-block"> +>>> try: +... raise Exception("Oof") +... except Exception, e: +... print "Caught an exception: %s" % e +Caught an exception: Oof +</pre> +</blockquote> +</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> +<p><a class="reference" href="http://www.python.org/dev/peps/pep-0255/">Generators</a>, <a class="reference" href="http://docs.python.org/lib/typeiter.html">iterators</a>, and <a class="reference" href="http://www.python.org/dev/peps/pep-0289/">generator expressions</a> work almost +identically to their JavaScript 1.7 counterparts. And while I'm not +sure if Python was the inspiration for them, JavaScript 1.7's array +comprehensions are almost identical to Python's <a class="reference" href="http://docs.python.org/tut/node7.html#SECTION007140000000000000000">list comprehensions</a>.</p> +</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 +in <a class="reference" href="http://www.python.org/dev/peps/pep-0008">PEP 8</a>.</p> +</div> +<div class="section"> +<h1><a id="documentation-testing" name="documentation-testing">Documentation Testing</a></h1> +<p>One of the most useful features of Python is one of its standard +library modules. The <a class="reference" href="http://docs.python.org/lib/module-doctest.html">doctest</a> module allows you to test +interactive interpreter excerpts embedded either in the docstrings of +your Python code or separate files to verify their correctness. It's +an excellent way to turn your documentation into your unit tests, and +it's also how the document you're reading right now is tested for +accuracy.</p> +</div> +<div class="section"> +<h1><a id="more-resources" name="more-resources">More Resources</a></h1> +<p>If you like what you've seen of the language, I highly recommend +reading David Beazley's <a class="reference" href="http://www.amazon.com/Python-Essential-Reference-Developers-Library/dp/0672328623">Python Essential Reference</a>, which features +a much more thorough and concise overview of the language.</p> +<p>It's also a good idea to become involved with the Python community; +it's very friendly and helpful. In particular, you may want to join +the <a class="reference" href="http://mail.python.org/mailman/listinfo/tutor">tutor mailing list</a>, and a <a class="reference" href="http://wiki.python.org/moin/LocalUserGroups">local user group</a> if your area has +one.</p> +</div> +</div> +</body> +</html>