diff --git a/dip2 b/dip2 index dee7d9a..f18bbf2 100644 --- a/dip2 +++ b/dip2 @@ -743,14 +743,14 @@ In fact, every Python function returns a value; if the function ever executes a

So Python is both dynamically typed (because it doesn't use explicit datatype declarations) and strongly typed (because once a variable has a datatype, it actually matters).

2.3. Documenting Functions

-

You can document a Python function by giving it a doc string. -

Example 2.2. Defining the buildConnectionString Function's doc string

+

You can document a Python function by giving it a docstring. +

Example 2.2. Defining the buildConnectionString Function's docstring

 def buildConnectionString(params):
     """Build a connection string from a dictionary of parameters.
 
     Returns string."""

Triple quotes signify a multi-line string. Everything between the start and end quotes is part of a single string, including carriage returns and other quote characters. You can use them anywhere, but you'll see them most often used when defining - a doc string. + a docstring.

@@ -760,31 +760,26 @@ def buildConnectionString(params):
Note
-

Everything between the triple quotes is the function's doc string, which documents what the function does. A doc string, if it exists, must be the first thing defined in a function (that is, the first thing after the colon). You don't technically -need to give your function a doc string, but you always should. I know you've heard this in every programming class you've ever taken, but Python gives you an added incentive: the doc string is available at runtime as an attribute of the function. +

Everything between the triple quotes is the function's docstring, which documents what the function does. A docstring, if it exists, must be the first thing defined in a function (that is, the first thing after the colon). You don't technically +need to give your function a docstring, but you always should. I know you've heard this in every programming class you've ever taken, but Python gives you an added incentive: the docstring is available at runtime as an attribute of the function.

-
Note
Many Python IDEs use the doc string to provide context-sensitive documentation, so that when you type a function name, its doc string appears as a tooltip. This can be incredibly helpful, but it's only as good as the doc strings you write. +Many Python IDEs use the docstring to provide context-sensitive documentation, so that when you type a function name, its docstring appears as a tooltip. This can be incredibly helpful, but it's only as good as the docstrings you write.
-

-

Further Reading on Documenting Functions

- + +

2.4. Everything Is an Object

In case you missed it, I just said that Python functions have attributes, and that those attributes are available at runtime.

A function, like everything else in Python, is an object.

Open your favorite Python IDE and follow along: -

Example 2.3. Accessing the buildConnectionString Function's doc string

>>> import odbchelper            1
+

Example 2.3. Accessing the buildConnectionString Function's docstring

>>> import odbchelper            1
 >>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}
 >>> print odbchelper.buildConnectionString(params) 2
 server=mpilgrim;uid=sa;database=master;pwd=secret
@@ -862,7 +857,7 @@ Returns string.

2.4.2. What's an Object?

-

Everything in Python is an object, and almost everything has attributes and methods. All functions have a built-in attribute __doc__, which returns the doc string defined in the function's source code. The sys module is an object which has (among other things) an attribute called path. And so forth. +

Everything in Python is an object, and almost everything has attributes and methods. All functions have a built-in attribute __doc__, which returns the docstring defined in the function's source code. The sys module is an object which has (among other things) an attribute called path. And so forth.

Still, this begs the question. What is an object? Different programming languages define “object” in different ways. In some, it means that all objects must have attributes and methods; in others, it means that all objects are subclassable. In Python, the definition is looser; some objects have neither attributes nor methods (more on this in Chapter 3), and not all objects are subclassable (more on this in Chapter 5). But everything is an object in the sense that it can be assigned to a variable or passed as an argument to a function (more in this in Chapter 4).

This is so important that I'm going to repeat it in case you missed it the first few times: everything in Python is an object. Strings are objects. Lists are objects. Functions are objects. Even modules are objects. @@ -882,7 +877,7 @@ def buildConnectionString(params): Returns string.""" return ";".join(["%s=%s" % (k, v) for k, v in params.items()])

Code blocks are defined by their indentation. By "code block", I mean functions, if statements, for loops, while loops, and so forth. Indenting starts a block and unindenting ends it. There are no explicit braces, brackets, or keywords. -This means that whitespace is significant, and must be consistent. In this example, the function code (including the doc string) is indented four spaces. It doesn't need to be four spaces, it just needs to be consistent. The first line that is not +This means that whitespace is significant, and must be consistent. In this example, the function code (including the docstring) is indented four spaces. It doesn't need to be four spaces, it just needs to be consistent. The first line that is not indented is outside the function.

Example 2.6, “if Statements” shows an example of code indentation with if statements.

Example 2.6. if Statements

@@ -2044,9 +2039,9 @@ if __name__ == "__main__":
 
 
  • Writing Python programs and running them from within your IDE, or from the command line -
  • Importing modules and calling their functions +
  • Importing modules and calling their functions -
  • Declaring functions and using doc strings, local variables, and proper indentation +
  • Declaring functions and using docstrings, local variables, and proper indentation
  • Defining dictionaries, tuples, and lists
  • Accessing attributes and methods of any object, including strings, lists, dictionaries, functions, and modules @@ -2067,7 +2062,7 @@ functions whose names you don't even know ahead of time.

    Example 4.1. apihelper.py

    If you have not already done so, you can download this and other examples used in this book.

     def info(object, spacing=10, collapse=1): 1 2 3
    -    """Print methods and doc strings.
    +    """Print methods and docstrings.
         
         Takes module, class, list, dictionary, or string."""
         methodList = [method for method in dir(object) if callable(getattr(object, method))]
    @@ -2089,7 +2084,7 @@ if __name__ == "__main__":                2 
     
    -The info function has a multi-line doc string that succinctly describes the function's purpose.  Note that no return value is mentioned; this function will be used solely
    +The info function has a multi-line docstring that succinctly describes the function's purpose.  Note that no return value is mentioned; this function will be used solely
                 for its effects, rather than its value.
     
     
    @@ -2103,7 +2098,7 @@ if __name__ == "__main__":                4 
     
     The if __name__ trick allows this program do something useful when run by itself, without interfering with its use as a module for other programs.
    -             In this case, the program simply prints out the doc string of the info function.
    +             In this case, the program simply prints out the docstring of the info function.
     
     
     
    @@ -2114,7 +2109,7 @@ if __name__ == "__main__":                info function is designed to be used by you, the programmer, while working in the Python IDE.  It takes any object that has functions or methods (like a module, which has functions, or a list, which has methods) and
    -prints out the functions and their doc strings.
    +prints out the functions and their docstrings.
     

    Example 4.2. Sample Usage of apihelper.py

    >>> from apihelper import info
     >>> li = []
     >>> info(li)
    @@ -2126,7 +2121,7 @@ insert     L.insert(index, object) -- insert object before index
     pop        L.pop([index]) -> item -- remove and return item at index (default last)
     remove     L.remove(value) -- remove first occurrence of value
     reverse    L.reverse() -- reverse *IN PLACE*
    -sort       L.sort([cmpfunc]) -- sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1

    By default the output is formatted to be easy to read. Multi-line doc strings are collapsed into a single long line, but this option can be changed by specifying 0 for the collapse argument. If the function names are longer than 10 characters, you can specify a larger value for the spacing argument to make the output easier to read. +sort L.sort([cmpfunc]) -- sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1

    By default the output is formatted to be easy to read. Multi-line docstrings are collapsed into a single long line, but this option can be changed by specifying 0 for the collapse argument. If the function names are longer than 10 characters, you can specify a larger value for the spacing argument to make the output easier to read.

    Example 4.3. Advanced Usage of apihelper.py

    >>> import odbchelper
     >>> info(odbchelper)
     buildConnectionString Build a connection string from a dictionary Returns string.
    @@ -2307,7 +2302,7 @@ True
    3 -This is where it really gets interesting. odbchelper is a module, so dir(odbchelper) returns a list of all kinds of stuff defined in the module, including built-in attributes, like __name__, __doc__, and whatever other attributes and methods you define. In this case, odbchelper has only one user-defined method, the buildConnectionString function described in Chapter 2. +This is where it really gets interesting. odbchelper is a module, so dir(odbchelper) returns a list of all kinds of stuff defined in the module, including built-in attributes, like __name__, __doc__, and whatever other attributes and methods you define. In this case, odbchelper has only one user-defined method, the buildConnectionString function described in Chapter 2. @@ -2358,7 +2353,7 @@ True 5 -Any callable object may have a doc string. By using the callable function on each of an object's attributes, you can determine which attributes you care about (methods, functions, classes) +Any callable object may have a docstring. By using the callable function on each of an object's attributes, you can determine which attributes you care about (methods, functions, classes) and which you want to ignore (constants and so on) without knowing anything about the object ahead of time. @@ -2790,7 +2785,7 @@ a test 1 -This is a multiline string, defined by escape characters instead of triple quotes. \n is a carriage return, and \t is a tab character. +This is a multiline string, defined by escape characters instead of triple quotes. \n is a carriage return, and \t is a tab character. @@ -2802,7 +2797,7 @@ a test 3 -You can normalize whitespace by splitting a string with split and then rejoining it with join, using a single space as a delimiter. This is what the info function does to collapse multi-line doc strings into a single line. +You can normalize whitespace by splitting a string with split and then rejoining it with join, using a single space as a delimiter. This is what the info function does to collapse multi-line docstrings into a single line. @@ -2836,7 +2831,7 @@ a test square brackets.

    Now, let's take it from the end and work backwards. The

     for method in methodList

    shows that this is a list comprehension. As you know, methodList is a list of all the methods you care about in object. So you're looping through that list with method. -

    Example 4.22. Getting a doc string Dynamically

    >>> import odbchelper
    +

    Example 4.22. Getting a docstring Dynamically

    >>> import odbchelper
     >>> object = odbchelper 1
     >>> method = 'buildConnectionString'      2
     >>> getattr(object, method)               3
    @@ -2867,12 +2862,12 @@ for method in methodList

    shows that this is a 4 -Now, printing the actual doc string of the method is easy. +Now, printing the actual docstring of the method is easy. -

    The next piece of the puzzle is the use of str around the doc string. As you may recall, str is a built-in function that coerces data into a string. But a doc string is always a string, so why bother with the str function? The answer is that not every function has a doc string, and if it doesn't, its __doc__ attribute is None. -

    Example 4.23. Why Use str on a doc string?

    >>> >>> def foo(): print 2
    +

    The next piece of the puzzle is the use of str around the docstring. As you may recall, str is a built-in function that coerces data into a string. But a docstring is always a string, so why bother with the str function? The answer is that not every function has a docstring, and if it doesn't, its __doc__ attribute is None. +

    Example 4.23. Why Use str on a docstring?

    >>> >>> def foo(): print 2
     >>> >>> foo()
     2
     >>> >>> foo.__doc__     1
    @@ -2885,7 +2880,7 @@ True
     
     1 
     
    -You can easily define a function that has no doc string, so its __doc__ attribute is None.  Confusingly, if you evaluate the __doc__ attribute directly, the Python IDE prints nothing at all, which makes sense if you think about it, but is still unhelpful.
    +You can easily define a function that has no docstring, so its __doc__ attribute is None.  Confusingly, if you evaluate the __doc__ attribute directly, the Python IDE prints nothing at all, which makes sense if you think about it, but is still unhelpful.
     
     
     
    @@ -2921,7 +2916,7 @@ True
     
     1 
     
    -ljust pads the string with spaces to the given length.  This is what the info function uses to make two columns of output and line up all the doc strings in the second column.
    +ljust pads the string with spaces to the given length.  This is what the info function uses to make two columns of output and line up all the docstrings in the second column.
     
     
     
    @@ -2931,7 +2926,7 @@ True
     
     
     
    -

    You're almost finished. Given the padded method name from the ljust method and the (possibly collapsed) doc string from the call to processFunc, you concatenate the two and get a single string. Since you're mapping methodList, you end up with a list of strings. Using the join method of the string "\n", you join this list into a single string, with each element of the list on a separate line, and print the result. +

    You're almost finished. Given the padded method name from the ljust method and the (possibly collapsed) docstring from the call to processFunc, you concatenate the two and get a single string. Since you're mapping methodList, you end up with a list of strings. Using the join method of the string "\n", you join this list into a single string, with each element of the list on a separate line, and print the result.

    Example 4.25. Printing a List

    >>> li = ['a', 'b', 'c']
     >>> print "\n".join(li) 1
     a
    @@ -2954,7 +2949,7 @@ c

    The apihelper.py program and its output should now make perfect sense.

     def info(object, spacing=10, collapse=1):
    -    """Print methods and doc strings.
    +    """Print methods and docstrings.
         
         Takes module, class, list, dictionary, or string."""
         methodList = [method for method in dir(object) if callable(getattr(object, method))]
    @@ -2998,7 +2993,7 @@ sort       L.sort([cmpfunc]) -- sort *IN PLACE*; if given, cmpfunc(x, y) -> -1,
     

    Chapter 5. Objects and Object-Orientation

    This chapter, and pretty much every chapter after this, deals with object-oriented Python programming.

    5.1. Diving In

    -

    Here is a complete, working Python program. Read the doc strings of the module, the classes, and the functions to get an overview of what this program does and how it works. As usual, don't +

    Here is a complete, working Python program. Read the docstrings of the module, the classes, and the functions to get an overview of what this program does and how it works. As usual, don't worry about the stuff you don't understand; that's what the rest of the chapter is for.

    Example 5.1. fileinfo.py

    If you have not already done so, you can download this and other examples used in this book.

    @@ -3141,7 +3136,7 @@ comment=http://mp3.com/artists/95/vxp

    5

    Here is the basic from module import syntax:

     from UserDict import UserDict
    -

    This is similar to the import module syntax that you know and love, but with an important difference: the attributes and methods of the imported module types are imported directly into the local namespace, so they are available directly, without qualification by module name. You +

    This is similar to the import module syntax that you know and love, but with an important difference: the attributes and methods of the imported module types are imported directly into the local namespace, so they are available directly, without qualification by module name. You can import individual items or use from module import * to import everything. @@ -3300,7 +3295,7 @@ class FileInfo(UserDict): - @@ -3418,7 +3413,7 @@ class FileInfo(UserDict): - @@ -3991,7 +3986,7 @@ call it directly (even from outside the fileinfo m - @@ -4025,7 +4020,7 @@ AttributeError: 'MP3FileInfo' instance has no attribute '__parse'Before diving into the next chapter, make sure you're comfortable doing all of these things:
      -
    • Importing modules using either import module or from module import +
    • Importing modules using either import module or from module import
    • Defining and instantiating classes
    • Defining __init__ methods and other special class methods, and understanding when they are called @@ -6041,7 +6036,7 @@ they solve.

      Chapter 8. HTML Processing

      8.1. Diving in

      I often see questions on comp.lang.python like “How can I list all the [headers|images|links] in my HTML document?” “How do I parse/translate/munge the text of my HTML document but leave the tags alone?” “How can I add/remove/quote attributes of all my HTML tags at once?” This chapter will answer all of these questions. -

      Here is a complete, working Python program in two parts. The first part, BaseHTMLProcessor.py, is a generic tool to help you process HTML files by walking through the tags and text blocks. The second part, dialect.py, is an example of how to use BaseHTMLProcessor.py to translate the text of an HTML document but leave the tags alone. Read the doc strings and comments to get an overview of what's going on. Most of it will seem like black magic, because it's not obvious how +

      Here is a complete, working Python program in two parts. The first part, BaseHTMLProcessor.py, is a generic tool to help you process HTML files by walking through the tags and text blocks. The second part, dialect.py, is an example of how to use BaseHTMLProcessor.py to translate the text of an HTML document but leave the tags alone. Read the docstrings and comments to get an overview of what's going on. Most of it will seem like black magic, because it's not obvious how any of these class methods ever get called. Don't worry, all will be revealed in due time.

      Example 8.1. BaseHTMLProcessor.py

      If you have not already done so, you can download this and other examples used in this book.

      @@ -6712,7 +6707,7 @@ from __future__ import nested_scopes
    Note
    1 Classes can (and should) have doc strings too, just like modules and functions. +Classes can (and should) have docstrings too, just like modules and functions.
    3 You can access the instance's doc string just as with a function or a module. All instances of a class share the same doc string. +You can access the instance's docstring just as with a function or a module. All instances of a class share the same docstring.
    Note
    In Python, all special methods (like __setitem__) and built-in attributes (like __doc__) follow a standard naming convention: they both start with and end with two underscores. Don't name your own methods and +In Python, all special methods (like __setitem__) and built-in attributes (like __doc__) follow a standard naming convention: they both start with and end with two underscores. Don't name your own methods and attributes this way, because it will only confuse you (and others) later.

    What locals does for the local (function) namespace, globals does for the global (module) namespace. globals is more exciting, though, because a module's namespace is more exciting.[3] Not only does the module's namespace include module-level variables and constants, it includes all the functions and classes defined in the module. Plus, it includes anything that was imported into the module. -

    Remember the difference between from module import and import module? With import module, the module itself is imported, but it retains its own namespace, which is why you need to use the module name to access +

    Remember the difference between from module import and import module? With import module, the module itself is imported, but it retains its own namespace, which is why you need to use the module name to access any of its functions or attributes: module.function. But with from module import, you're actually importing specific functions and attributes from another module into your own namespace, which is why you access them directly without referencing the original module they came from. With the globals function, you can actually see this happen.

    Example 8.11. Introducing globals

    @@ -6952,7 +6947,7 @@ at all. It is this last side effect that you can take advantage of. 1 -Note that the attribute values of the href attributes in the <a> tags are not properly quoted. (Also note that you're using triple quotes for something other than a doc string. And directly in the IDE, no less. They're very useful.) +Note that the attribute values of the href attributes in the <a> tags are not properly quoted. (Also note that you're using triple quotes for something other than a docstring. And directly in the IDE, no less. They're very useful.) @@ -7138,7 +7133,7 @@ def translate(url, dialectName="chef"): 2 -Hey, wait a minute, there's an import statement in this function! That's perfectly legal in Python. You're used to seeing import statements at the top of a program, which means that the imported module is available anywhere in the program. But you can +Hey, wait a minute, there's an import statement in this function! That's perfectly legal in Python. You're used to seeing import statements at the top of a program, which means that the imported module is available anywhere in the program. But you can also import modules within a function, which means that the imported module is only available within the function. If you have a module that is only ever used in one function, this is an easy way to make your code more modular. (When you find that your weekend hack has turned into an 800-line work of art and decide to split it up into a dozen reusable modules, you'll @@ -12093,7 +12088,7 @@ FAILED (failures=10, errors=2) 1 -Running the script runs unittest.main(), which runs each test case, which is to say each method defined in each class within romantest.py. For each test case, it prints out the doc string of the method and whether that test passed or failed. As expected, none of the test cases passed. +Running the script runs unittest.main(), which runs each test case, which is to say each method defined in each class within romantest.py. For each test case, it prints out the docstring of the method and whether that test passed or failed. As expected, none of the test cases passed. @@ -13406,7 +13401,7 @@ OK 3 1 -Just a note in passing here: this time, I ran the unit test without the -v option, so instead of the full doc string for each test, you only get a dot for each test that passes. (If a test failed, you'd get an F, and if it had an error, you'd get an E. You'd still get complete tracebacks for each failure and error, so you could track down any problems.) +Just a note in passing here: this time, I ran the unit test without the -v option, so instead of the full docstring for each test, you only get a dot for each test that passes. (If a test failed, you'd get an F, and if it had an error, you'd get an E. You'd still get complete tracebacks for each failure and error, so you could track down any problems.) diff --git a/dip3.css b/dip3.css index 88f7468..9941ef5 100644 --- a/dip3.css +++ b/dip3.css @@ -5,7 +5,7 @@ a:hover{border-bottom:1px solid} a:link{color:#1b67c9} a:visited{color:darkorchid} h1 a,h2 a,h3 a,#nav a{color:inherit !important} -abbr{letter-spacing:0.1em;text-transform:lowercase;font-variant:small-caps} +abbr,acronym{letter-spacing:0.1em;text-transform:lowercase;font-variant:small-caps} h1,h2,h3,p,ul,ol,#nav{margin:1.75em 0} li ol{margin:0} h1,h2,h3{font-size:medium} @@ -25,14 +25,17 @@ th{text-align:left;padding:0 0.5em;vertical-align:baseline;border:1px dotted} th,td{width:45%;vertical-align:top} td{border:1px dotted;padding:0 0.5em} th:first-child{width:10%;text-align:center} -span,.note p:first-child,tr + tr th:first-child{font-family:'Arial Unicode MS',sans-serif;font-style:normal} -table.simple th{font-family:inherit !important} -.note p:first-child{float:left;font-size:xx-large;line-height:0.875em;margin:0 0.22em 0 0} +span,tr + tr th:first-child{font-family:'Arial Unicode MS',sans-serif;font-style:normal} .q span{font-size:large} +.note{margin-left:4.94em} +.note span{display:block;float:left;font-size:xx-large;line-height:0.875em;margin:0 0.22em 0 -1.22em} +table.simple th{font-family:inherit !important} body{counter-reset:h1} h1:before{counter-increment:h1;content:counter(h1) ". "} h1{counter-reset:h2} h2:before{counter-increment:h2;content:counter(h1) "." counter(h2) ". "} h2{counter-reset:h3} h3:before{counter-increment:h3;content:counter(h1) "." counter(h2) "." counter(h3) ". "} -tr.hover,li.hover{background:#eee;color:inherit;cursor:default} \ No newline at end of file +tr.hover,li.hover{background:#eee;color:inherit;cursor:default} +.fr{width:auto;margin-top:4.308em;border:1px dotted} +.fr h4{margin-top:-1.2em;margin-left:-1em;width:8.5em;border:1px dotted;padding: 3px 3px 3px 13px;background:#fff;color:inherit;position:relative} \ No newline at end of file diff --git a/porting-code-to-python-3-with-2to3.html b/porting-code-to-python-3-with-2to3.html index 3fff815..583d260 100644 --- a/porting-code-to-python-3-with-2to3.html +++ b/porting-code-to-python-3-with-2to3.html @@ -567,8 +567,7 @@ for an_iterator in a_sequence_of_iterators: reduce(a, b, c)
    -

    ☞ -

    The version of 2to3 that shipped with Python 3.0 would not fix the reduce() function automatically. The fix first appeared in the 2to3 script that shipped with Python 3.1. +

    The version of 2to3 that shipped with Python 3.0 would not fix the reduce() function automatically. The fix first appeared in the 2to3 script that shipped with Python 3.1.

    apply() global function

    Python 2 had a global function called apply(), which took a function f and a list [a, b, c] and returned f(a, b, c). In Python 3, the apply() function no longer exists. Instead, there is a new function calling syntax that allows you to pass a list and have Python apply the list as the function's arguments. @@ -646,8 +645,7 @@ reduce(a, b, c)

    exec(compile(open("a_filename").read(), "a_filename", "exec"))
    -

    ☞ -

    The version of 2to3 that shipped with Python 3.0 would not fix the execfile statement automatically. The fix first appeared in the 2to3 script that shipped with Python 3.1. +

    The version of 2to3 that shipped with Python 3.0 would not fix the execfile statement automatically. The fix first appeared in the 2to3 script that shipped with Python 3.1.

    repr literals (backticks)

    In Python 2, there was a special syntax of wrapping any object in backticks (like `x`) to get a representation of the object. In Python 3, this capability still exists, but you can no longer use backticks to get it. Instead, use the global repr() function. @@ -714,8 +712,7 @@ except:

  • Similarly, if you use a fallback to catch all exceptions, the syntax is identical.
    -

    ☞ -

    You should never use a fallback to catch all exceptions when importing modules (or most other times). Doing so will catch things like KeyboardInterrupt (if the user pressed Ctrl-C to interrupt the program) and can make it more difficult to debug errors. +

    You should never use a fallback to catch all exceptions when importing modules (or most other times). Doing so will catch things like KeyboardInterrupt (if the user pressed Ctrl-C to interrupt the program) and can make it more difficult to debug errors.

    raise statement

    The syntax for raising your own exceptions has changed slightly between Python 2 and Python 3. @@ -1067,8 +1064,7 @@ except: isinstance(x, (int, float))

    -

    ☞ -

    The version of 2to3 that shipped with Python 3.0 would not fix these cases of isinstance() automatically. The fix first appeared in the 2to3 script that shipped with Python 3.1. +

    The version of 2to3 that shipped with Python 3.0 would not fix these cases of isinstance() automatically. The fix first appeared in the 2to3 script that shipped with Python 3.1.

    basestring datatype

    Python 2 had two string types: Unicode and non-Unicode. But there was also another type, basestring. It was an abstract type, a superclass for both the str and unicode types. It couldn't be called or instantiated directly, but you could pass it to the global isinstance() function to check whether an object was either a Unicode or non-Unicode string. In Python 3, there is only one string type, so basestring has no reason to exist. @@ -1187,8 +1183,7 @@ except:

    set() literals (explicit)

    In Python 2, the only way to define a literal set in your code was to call set(a_sequence). This still works in Python 3, but a clearer way of doing it is to use the new set literal notation: curly braces. (Dictionaries are also defined with curly braces, which makes sense once you think about it, because dictionaries are just sets of key-value pairs.)

    -

    ☞ -

    The 2to3 script will not fix set() literals by default. To enable this fix, specify -f set_literal on the command line when you call 2to3. +

    The 2to3 script will not fix set() literals by default. To enable this fix, specify -f set_literal on the command line when you call 2to3.

    skip over this table @@ -1210,8 +1205,7 @@ except:

    buffer() global function (explicit)

    Python objects implemented in C can export a “buffer interface,” which is a block of memory that is directly readable and writeable without copying. (That is exactly as powerful and scary as it sounds.) In Python 3, buffer() has been renamed to memoryview(). (It's a little more complicated than that, but you can almost certainly ignore the differences.)

    -

    ☞ -

    The 2to3 script will not fix the buffer() function by default. To enable this fix, specify -f buffer on the command line when you call 2to3. +

    The 2to3 script will not fix the buffer() function by default. To enable this fix, specify -f buffer on the command line when you call 2to3.

    skip over this table

    @@ -1227,8 +1221,7 @@ except:

    Whitespace around commas (explicit)

    Despite being draconian about whitespace for indenting and outdenting, Python is actually quite liberal about whitespace in other areas. Within lists, tuples, sets, and dictionaries, whitespace can appear before and after commas with no ill effects. However, the Python style guide states that commas should be preceded by zero spaces and followed by one. Although this is purely an aesthetic issue (the code works either way, in both Python 2 and Python 3), the 2to3 script can optionally fix this for you.

    -

    ☞ -

    The 2to3 script will not fix whitespace around commas by default. To enable this fix, specify -f wscomma on the command line when you call 2to3. +

    The 2to3 script will not fix whitespace around commas by default. To enable this fix, specify -f wscomma on the command line when you call 2to3.

    skip over this table

    @@ -1247,8 +1240,7 @@ except:

    Common idioms (explicit)

    There were a number of common idioms built up in the Python community. Some, like the while 1: loop, date back to Python 1. (Python didn't have a true boolean type until version 2.3, so developers used 1 and 0 instead.) Modern Python programmers should train their brains to use modern versions of these idioms instead.

    -

    ☞ -

    The 2to3 script will not fix common idioms by default. To enable this fix, specify -f idioms on the command line when you call 2to3. +

    The 2to3 script will not fix common idioms by default. To enable this fix, specify -f idioms on the command line when you call 2to3.

    skip over this table

    diff --git a/your-first-python-program.html b/your-first-python-program.html index 72a300c..28e0f16 100644 --- a/your-first-python-program.html +++ b/your-first-python-program.html @@ -12,30 +12,16 @@ body{counter-reset:h1 1}

    Your first Python program

    -

    FIXME
    FIXME +

    Don’t bury your burden in saintly silence. You have a problem? Great. Rejoice, dive in, and investigate.
    Ven. Henepola Gunararatana

    1. Diving in
    2. Declaring functions +
    3. Documenting functions

    Diving in

    -

    You know how other books go on and on about programming fundamentals and finally work up to building a complete, working program? Let's skip all that. -

    Here is a complete, working Python program. It probably makes absolutely no sense to you. Don't worry about that, because you're going to dissect it line by line. But read through it first and see what, if anything, you can make of it. -

    """Convert file sizes to human-readable form.
    -
    -Available functions:
    -approximate_size(size, a_kilobyte_is_1024_bytes)
    -    takes a file size and returns a human-readable string
    -
    -Examples:
    ->>> approximate_size(1024)
    -'1.0 KiB'
    ->>> approximate_size(1000, False)
    -'1.0 KB'
    -
    -"""
    -
    -SUFFIXES = {1000: ('KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'),
    +

    You know how other books go on and on about programming fundamentals and finally work up to building something useful? Let's skip all that. Here is a complete, working Python program. It probably makes absolutely no sense to you. Don't worry about that, because you're going to dissect it line by line. But read through it first and see what, if anything, you can make of it. +

    SUFFIXES = {1000: ('KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'),
                 1024: ('KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB')}
     
     def approximate_size(size, a_kilobyte_is_1024_bytes=True):
    @@ -77,13 +63,11 @@ if __name__ == "__main__":
     

    Note that the keyword def starts the function declaration, followed by the function name, followed by the arguments in parentheses. Multiple arguments are separated with commas.

    Also note that the function doesn't define a return datatype. Python functions do not specify the datatype of their return value; they don't even specify whether or not they return a value. (In fact, every Python function returns a value; if the function ever executes a return statement, it will return that value, otherwise it will return None, the Python null value.)

    -

    ☞ -

    In some languages, functions (that return a value) start with function, and subroutines (that do not return a value) start with sub. There are no subroutines in Python. Everything is a function, all functions return a value (even if it's None), and all functions start with def. +

    In some languages, functions (that return a value) start with function, and subroutines (that do not return a value) start with sub. There are no subroutines in Python. Everything is a function, all functions return a value (even if it's None), and all functions start with def.

    The approximate_size function takes the two arguments — size and a_kilobyte_is_1024_bytes — but neither argument specifies a datatype. (As you might guess from the =True syntax, the second argument is a boolean. You'll learn what that syntax does in [FIXME xref].) In Python, variables are never explicitly typed. Python figures out what type a variable is and keeps track of it internally.

    -

    ☞ -

    In Java, C++, and other statically-typed languages, you must specify the datatype of the function return value and each function argument. In Python, you never explicitly specify the datatype of anything. Based on what value you assign, Python keeps track of the datatype internally. +

    In Java, C++, and other statically-typed languages, you must specify the datatype of the function return value and each function argument. In Python, you never explicitly specify the datatype of anything. Based on what value you assign, Python keeps track of the datatype internally.

    How Python's Datatypes Compare to Other Programming Languages

    An erudite reader sent me this explanation of how Python compares to other programming languages: @@ -108,10 +92,35 @@ if __name__ == "__main__":

    Weakly typedC, Objective-CJavaScript, Perl 5, PHP
    Strongly typedPascal, JavaPython, Ruby
    +

    Documenting functions

    +

    You can document a Python function by giving it a docstring. In this program, the approximate_size function has a docstring: +

    def approximate_size(size, a_kilobyte_is_1024_bytes=True):
    +    """Convert a file size to human-readable form.
     
    +    Keyword arguments:
    +    size -- file size in bytes
    +    a_kilobyte_is_1024_bytes -- if True (default), use multiples of 1024
    +                                if False, use multiples of 1000
     
    +    Returns: string
     
    -
    +    """
    +

    Triple quotes signify a multi-line string. Everything between the start and end quotes is part of a single string, including carriage returns and other quote characters. You can use them anywhere, but you'll see them most often used when defining a docstring. +

    +

    Triple quotes are also an easy way to define a string with both single and double quotes, like qq/.../ in Perl 5. +

    +

    Everything between the triple quotes is the function's docstring, which documents what the function does. A docstring, if it exists, must be the first thing defined in a function (that is, on the next line after the function declaration). You don't technically need to give your function a docstring, but you always should. I know you've heard this in every programming class you've ever taken, but Python gives you an added incentive: the docstring is available at runtime as an attribute of the function. +

    +

    Many Python IDEs use the docstring to provide context-sensitive documentation, so that when you type a function name, its docstring appears as a tooltip. This can be incredibly helpful, but it's only as good as the docstrings you write. +

    +

    © 2001-4, 2009 ark Pilgrim, CC-BY-3.0