diff options
Diffstat (limited to 'Doc/tutorial')
-rw-r--r-- | Doc/tutorial/appendix.rst | 6 | ||||
-rw-r--r-- | Doc/tutorial/classes.rst | 285 | ||||
-rw-r--r-- | Doc/tutorial/controlflow.rst | 464 | ||||
-rw-r--r-- | Doc/tutorial/datastructures.rst | 318 | ||||
-rw-r--r-- | Doc/tutorial/errors.rst | 260 | ||||
-rw-r--r-- | Doc/tutorial/floatingpoint.rst | 268 | ||||
-rw-r--r-- | Doc/tutorial/index.rst | 1 | ||||
-rw-r--r-- | Doc/tutorial/inputoutput.rst | 413 | ||||
-rw-r--r-- | Doc/tutorial/interactive.rst | 157 | ||||
-rw-r--r-- | Doc/tutorial/interpreter.rst | 73 | ||||
-rw-r--r-- | Doc/tutorial/introduction.rst | 219 | ||||
-rw-r--r-- | Doc/tutorial/modules.rst | 253 | ||||
-rw-r--r-- | Doc/tutorial/stdlib.rst | 90 | ||||
-rw-r--r-- | Doc/tutorial/stdlib2.rst | 43 | ||||
-rw-r--r-- | Doc/tutorial/venv.rst | 216 | ||||
-rw-r--r-- | Doc/tutorial/whatnow.rst | 33 |
16 files changed, 1300 insertions, 1799 deletions
diff --git a/Doc/tutorial/appendix.rst b/Doc/tutorial/appendix.rst index 241a812..73b7d1b 100644 --- a/Doc/tutorial/appendix.rst +++ b/Doc/tutorial/appendix.rst @@ -40,7 +40,7 @@ Executable Python Scripts On BSD'ish Unix systems, Python scripts can be made directly executable, like shell scripts, by putting the line :: - #!/usr/bin/env python3.5 + #!/usr/bin/env python (assuming that the interpreter is on the user's :envvar:`PATH`) at the beginning of the script and giving the file an executable mode. The ``#!`` must be the @@ -52,7 +52,7 @@ comment in Python. The script can be given an executable mode, or permission, using the :program:`chmod` command. -.. code-block:: shell-session +.. code-block:: bash $ chmod +x myscript.py @@ -107,7 +107,7 @@ of your user site-packages directory. Start Python and run this code:: >>> import site >>> site.getusersitepackages() - '/home/user/.local/lib/python3.5/site-packages' + '/home/user/.local/lib/python2.7/site-packages' Now you can create a file named :file:`usercustomize.py` in that directory and put anything you want in it. It will affect every invocation of Python, unless diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 0c0dca9..b17e150 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -4,12 +4,6 @@ Classes ******* -Classes provide a means of bundling data and functionality together. Creating -a new class creates a new *type* of object, allowing new *instances* of that -type to be made. Each class instance can have attributes attached to it for -maintaining its state. Class instances can also have methods (defined by its -class) for modifying its state. - Compared with other programming languages, Python's class mechanism adds classes with a minimum of new syntax and semantics. It is a mixture of the class mechanisms found in C++ and Modula-3. Python classes provide all the standard @@ -101,7 +95,7 @@ until the interpreter quits. The statements executed by the top-level invocation of the interpreter, either read from a script file or interactively, are considered part of a module called :mod:`__main__`, so they have their own global namespace. (The built-in names actually also live in a module; this is -called :mod:`builtins`.) +called :mod:`__builtin__`.) The local namespace for a function is created when the function is called, and deleted when the function returns or raises an exception that is not handled @@ -124,11 +118,10 @@ are directly accessible: * the outermost scope (searched last) is the namespace containing built-in names If a name is declared global, then all references and assignments go directly to -the middle scope containing the module's global names. To rebind variables -found outside of the innermost scope, the :keyword:`nonlocal` statement can be -used; if not declared nonlocal, those variables are read-only (an attempt to -write to such a variable will simply create a *new* local variable in the -innermost scope, leaving the identically named outer variable unchanged). +the middle scope containing the module's global names. Otherwise, all variables +found outside of the innermost scope are read-only (an attempt to write to such +a variable will simply create a *new* local variable in the innermost scope, +leaving the identically named outer variable unchanged). Usually, the local scope references the local names of the (textually) current function. Outside functions, the local scope references the same namespace as @@ -149,61 +142,9 @@ do not copy data --- they just bind names to objects. The same is true for deletions: the statement ``del x`` removes the binding of ``x`` from the namespace referenced by the local scope. In fact, all operations that introduce new names use the local scope: in particular, :keyword:`import` statements and -function definitions bind the module or function name in the local scope. - -The :keyword:`global` statement can be used to indicate that particular -variables live in the global scope and should be rebound there; the -:keyword:`nonlocal` statement indicates that particular variables live in -an enclosing scope and should be rebound there. - -.. _tut-scopeexample: - -Scopes and Namespaces Example ------------------------------ - -This is an example demonstrating how to reference the different scopes and -namespaces, and how :keyword:`global` and :keyword:`nonlocal` affect variable -binding:: - - def scope_test(): - def do_local(): - spam = "local spam" - - def do_nonlocal(): - nonlocal spam - spam = "nonlocal spam" - - def do_global(): - global spam - spam = "global spam" - - spam = "test spam" - do_local() - print("After local assignment:", spam) - do_nonlocal() - print("After nonlocal assignment:", spam) - do_global() - print("After global assignment:", spam) - - scope_test() - print("In global scope:", spam) - -The output of the example code is: - -.. code-block:: none - - After local assignment: test spam - After nonlocal assignment: nonlocal spam - After global assignment: nonlocal spam - In global scope: global spam - -Note how the *local* assignment (which is default) didn't change *scope_test*\'s -binding of *spam*. The :keyword:`nonlocal` assignment changed *scope_test*\'s -binding of *spam*, and the :keyword:`global` assignment changed the module-level -binding. - -You can also see that there was no previous binding for *spam* before the -:keyword:`global` assignment. +function definitions bind the module or function name in the local scope. (The +:keyword:`global` statement can be used to indicate that particular variables +live in the global scope.) .. _tut-firstclasses: @@ -334,7 +275,7 @@ code will print the value ``16``, without leaving a trace:: x.counter = 1 while x.counter < 10: x.counter = x.counter * 2 - print(x.counter) + print x.counter del x.counter The other kind of instance attribute reference is a *method*. A method is a @@ -369,7 +310,7 @@ object, and can be stored away and called at a later time. For example:: xf = x.f while True: - print(xf()) + print xf() will continue to print ``hello world`` until the end of time. @@ -380,11 +321,11 @@ Surely Python raises an exception when a function that requires an argument is called without any --- even if the argument isn't actually used... Actually, you may have guessed the answer: the special thing about methods is -that the instance object is passed as the first argument of the function. In our +that the object is passed as the first argument of the function. In our example, the call ``x.f()`` is exactly equivalent to ``MyClass.f(x)``. In general, calling a method with a list of *n* arguments is equivalent to calling the corresponding function with an argument list that is created by inserting -the method's instance object before the first argument. +the method's object before the first argument. If you still don't understand how methods work, a look at the implementation can perhaps clarify matters. When a non-data attribute of an instance is @@ -475,20 +416,12 @@ Random Remarks .. These should perhaps be placed more carefully... -If the same attribute name occurs in both an instance and in a class, -then attribute lookup prioritizes the instance:: - - >>> class Warehouse: - purpose = 'storage' - region = 'west' - - >>> w1 = Warehouse() - >>> print(w1.purpose, w1.region) - storage west - >>> w2 = Warehouse() - >>> w2.region = 'east' - >>> print(w2.purpose, w2.region) - storage east +Data attributes override method attributes with the same name; to avoid +accidental name conflicts, which may cause hard-to-find bugs in large programs, +it is wise to use some kind of convention that minimizes the chance of +conflicts. Possible conventions include capitalizing method names, prefixing +data attribute names with a small unique string (perhaps just an underscore), or +using verbs for methods and nouns for data attributes. Data attributes may be referenced by methods as well as by ordinary users ("clients") of an object. In other words, classes are not usable to implement @@ -621,8 +554,9 @@ Python has two built-in functions that work with inheritance: * Use :func:`issubclass` to check class inheritance: ``issubclass(bool, int)`` is ``True`` since :class:`bool` is a subclass of :class:`int`. However, - ``issubclass(float, int)`` is ``False`` since :class:`float` is not a - subclass of :class:`int`. + ``issubclass(unicode, str)`` is ``False`` since :class:`unicode` is not a + subclass of :class:`str` (they only share a common ancestor, + :class:`basestring`). @@ -631,8 +565,8 @@ Python has two built-in functions that work with inheritance: Multiple Inheritance -------------------- -Python supports a form of multiple inheritance as well. A class definition with -multiple base classes looks like this:: +Python supports a limited form of multiple inheritance as well. A class +definition with multiple base classes looks like this:: class DerivedClassName(Base1, Base2, Base3): <statement-1> @@ -641,37 +575,43 @@ multiple base classes looks like this:: . <statement-N> -For most purposes, in the simplest cases, you can think of the search for -attributes inherited from a parent class as depth-first, left-to-right, not -searching twice in the same class where there is an overlap in the hierarchy. -Thus, if an attribute is not found in :class:`DerivedClassName`, it is searched -for in :class:`Base1`, then (recursively) in the base classes of :class:`Base1`, -and if it was not found there, it was searched for in :class:`Base2`, and so on. - -In fact, it is slightly more complex than that; the method resolution order -changes dynamically to support cooperative calls to :func:`super`. This -approach is known in some other multiple-inheritance languages as -call-next-method and is more powerful than the super call found in -single-inheritance languages. - -Dynamic ordering is necessary because all cases of multiple inheritance exhibit -one or more diamond relationships (where at least one of the parent classes -can be accessed through multiple paths from the bottommost class). For example, -all classes inherit from :class:`object`, so any case of multiple inheritance -provides more than one path to reach :class:`object`. To keep the base classes -from being accessed more than once, the dynamic algorithm linearizes the search -order in a way that preserves the left-to-right ordering specified in each -class, that calls each parent only once, and that is monotonic (meaning that a -class can be subclassed without affecting the precedence order of its parents). -Taken together, these properties make it possible to design reliable and -extensible classes with multiple inheritance. For more detail, see +For old-style classes, the only rule is depth-first, left-to-right. Thus, if an +attribute is not found in :class:`DerivedClassName`, it is searched in +:class:`Base1`, then (recursively) in the base classes of :class:`Base1`, and +only if it is not found there, it is searched in :class:`Base2`, and so on. + +(To some people breadth first --- searching :class:`Base2` and :class:`Base3` +before the base classes of :class:`Base1` --- looks more natural. However, this +would require you to know whether a particular attribute of :class:`Base1` is +actually defined in :class:`Base1` or in one of its base classes before you can +figure out the consequences of a name conflict with an attribute of +:class:`Base2`. The depth-first rule makes no differences between direct and +inherited attributes of :class:`Base1`.) + +For :term:`new-style class`\es, the method resolution order changes dynamically +to support cooperative calls to :func:`super`. This approach is known in some +other multiple-inheritance languages as call-next-method and is more powerful +than the super call found in single-inheritance languages. + +With new-style classes, dynamic ordering is necessary because all cases of +multiple inheritance exhibit one or more diamond relationships (where at +least one of the parent classes can be accessed through multiple paths from the +bottommost class). For example, all new-style classes inherit from +:class:`object`, so any case of multiple inheritance provides more than one path +to reach :class:`object`. To keep the base classes from being accessed more +than once, the dynamic algorithm linearizes the search order in a way that +preserves the left-to-right ordering specified in each class, that calls each +parent only once, and that is monotonic (meaning that a class can be subclassed +without affecting the precedence order of its parents). Taken together, these +properties make it possible to design reliable and extensible classes with +multiple inheritance. For more detail, see https://www.python.org/download/releases/2.3/mro/. .. _tut-private: -Private Variables -================= +Private Variables and Class-local References +============================================ "Private" instance variables that cannot be accessed except from inside an object don't exist in Python. However, there is a convention that is followed @@ -723,12 +663,12 @@ Note that the mangling rules are designed mostly to avoid accidents; it still is possible to access or modify a variable that is considered private. This can even be useful in special circumstances, such as in the debugger. -Notice that code passed to ``exec()`` or ``eval()`` does not consider the -classname of the invoking class to be the current class; this is similar to the -effect of the ``global`` statement, the effect of which is likewise restricted -to code that is byte-compiled together. The same restriction applies to -``getattr()``, ``setattr()`` and ``delattr()``, as well as when referencing -``__dict__`` directly. +Notice that code passed to ``exec``, ``eval()`` or ``execfile()`` does not +consider the classname of the invoking class to be the current class; this is +similar to the effect of the ``global`` statement, the effect of which is +likewise restricted to code that is byte-compiled together. The same +restriction applies to ``getattr()``, ``setattr()`` and ``delattr()``, as well +as when referencing ``__dict__`` directly. .. _tut-odds: @@ -761,11 +701,60 @@ data from a string buffer instead, and pass it as an argument. or arithmetic operators, and assigning such a "pseudo-file" to sys.stdin will not cause the interpreter to read further input from it.) -Instance method objects have attributes, too: ``m.__self__`` is the instance -object with the method :meth:`m`, and ``m.__func__`` is the function object +Instance method objects have attributes, too: ``m.im_self`` is the instance +object with the method :meth:`m`, and ``m.im_func`` is the function object corresponding to the method. +.. _tut-exceptionclasses: + +Exceptions Are Classes Too +========================== + +User-defined exceptions are identified by classes as well. Using this mechanism +it is possible to create extensible hierarchies of exceptions. + +There are two new valid (semantic) forms for the :keyword:`raise` statement:: + + raise Class, instance + + raise instance + +In the first form, ``instance`` must be an instance of :class:`Class` or of a +class derived from it. The second form is a shorthand for:: + + raise instance.__class__, instance + +A class in an :keyword:`except` clause is compatible with an exception if it is +the same class or a base class thereof (but not the other way around --- an +except clause listing a derived class is not compatible with a base class). For +example, the following code will print B, C, D in that order:: + + class B: + pass + class C(B): + pass + class D(C): + pass + + for c in [B, C, D]: + try: + raise c() + except D: + print "D" + except C: + print "C" + except B: + print "B" + +Note that if the except clauses were reversed (with ``except B`` first), it +would have printed B, B, B --- the first matching except clause is triggered. + +When an error message is printed for an unhandled exception, the exception's +class name is printed, then a colon and a space, and finally the instance +converted to a string using the built-in function :func:`str`. + + .. _tut-iterators: Iterators @@ -775,45 +764,45 @@ By now you have probably noticed that most container objects can be looped over using a :keyword:`for` statement:: for element in [1, 2, 3]: - print(element) + print element for element in (1, 2, 3): - print(element) + print element for key in {'one':1, 'two':2}: - print(key) + print key for char in "123": - print(char) + print char for line in open("myfile.txt"): - print(line, end='') + print line, This style of access is clear, concise, and convenient. The use of iterators pervades and unifies Python. Behind the scenes, the :keyword:`for` statement calls :func:`iter` on the container object. The function returns an iterator -object that defines the method :meth:`~iterator.__next__` which accesses -elements in the container one at a time. When there are no more elements, -:meth:`~iterator.__next__` raises a :exc:`StopIteration` exception which tells the -:keyword:`!for` loop to terminate. You can call the :meth:`~iterator.__next__` method -using the :func:`next` built-in function; this example shows how it all works:: +object that defines the method :meth:`~iterator.next` which accesses elements +in the container one at a time. When there are no more elements, +:meth:`~iterator.next` raises a :exc:`StopIteration` exception which tells the +:keyword:`for` loop to terminate. +This example shows how it all works:: >>> s = 'abc' >>> it = iter(s) >>> it <iterator object at 0x00A1DB50> - >>> next(it) + >>> it.next() 'a' - >>> next(it) + >>> it.next() 'b' - >>> next(it) + >>> it.next() 'c' - >>> next(it) + >>> it.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> - next(it) + it.next() StopIteration Having seen the mechanics behind the iterator protocol, it is easy to add iterator behavior to your classes. Define an :meth:`__iter__` method which -returns an object with a :meth:`~iterator.__next__` method. If the class -defines :meth:`__next__`, then :meth:`__iter__` can just return ``self``:: +returns an object with a :meth:`~iterator.next` method. If the class +defines :meth:`~iterator.next`, then :meth:`__iter__` can just return ``self``:: class Reverse: """Iterator for looping over a sequence backwards.""" @@ -824,7 +813,7 @@ defines :meth:`__next__`, then :meth:`__iter__` can just return ``self``:: def __iter__(self): return self - def __next__(self): + def next(self): if self.index == 0: raise StopIteration self.index = self.index - 1 @@ -836,7 +825,7 @@ defines :meth:`__next__`, then :meth:`__iter__` can just return ``self``:: >>> iter(rev) <__main__.Reverse object at 0x00A1DB50> >>> for char in rev: - ... print(char) + ... print char ... m a @@ -863,7 +852,7 @@ easy to create:: :: >>> for char in reverse('golf'): - ... print(char) + ... print char ... f l @@ -872,7 +861,7 @@ easy to create:: Anything that can be done with generators can also be done with class-based iterators as described in the previous section. What makes generators so -compact is that the :meth:`__iter__` and :meth:`~generator.__next__` methods +compact is that the :meth:`__iter__` and :meth:`~generator.next` methods are created automatically. Another key feature is that the local variables and execution state are @@ -908,12 +897,15 @@ Examples:: >>> sum(x*y for x,y in zip(xvec, yvec)) # dot product 260 - >>> unique_words = set(word for line in page for word in line.split()) + >>> from math import pi, sin + >>> sine_table = dict((x, sin(x*pi/180)) for x in range(0, 91)) + + >>> unique_words = set(word for line in page for word in line.split()) >>> valedictorian = max((student.gpa, student.name) for student in graduates) >>> data = 'golf' - >>> list(data[i] for i in range(len(data)-1, -1, -1)) + >>> list(data[i] for i in range(len(data)-1,-1,-1)) ['f', 'l', 'o', 'g'] @@ -925,3 +917,4 @@ Examples:: namespace; the name :attr:`~object.__dict__` is an attribute but not a global name. Obviously, using this violates the abstraction of namespace implementation, and should be restricted to things like post-mortem debuggers. + diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 7dfd33a..2e1c122 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -10,45 +10,46 @@ flow control statements known from other languages, with some twists. .. _tut-if: -:keyword:`!if` Statements -========================= +:keyword:`if` Statements +======================== Perhaps the most well-known statement type is the :keyword:`if` statement. For example:: - >>> x = int(input("Please enter an integer: ")) + >>> x = int(raw_input("Please enter an integer: ")) Please enter an integer: 42 >>> if x < 0: ... x = 0 - ... print('Negative changed to zero') + ... print 'Negative changed to zero' ... elif x == 0: - ... print('Zero') + ... print 'Zero' ... elif x == 1: - ... print('Single') + ... print 'Single' ... else: - ... print('More') + ... print 'More' ... More There can be zero or more :keyword:`elif` parts, and the :keyword:`else` part is -optional. The keyword ':keyword:`!elif`' is short for 'else if', and is useful -to avoid excessive indentation. An :keyword:`!if` ... :keyword:`!elif` ... -:keyword:`!elif` ... sequence is a substitute for the ``switch`` or +optional. The keyword ':keyword:`elif`' is short for 'else if', and is useful +to avoid excessive indentation. An :keyword:`if` ... :keyword:`elif` ... +:keyword:`elif` ... sequence is a substitute for the ``switch`` or ``case`` statements found in other languages. .. _tut-for: -:keyword:`!for` Statements -========================== +:keyword:`for` Statements +========================= .. index:: statement: for + statement: for The :keyword:`for` statement in Python differs a bit from what you may be used to in C or Pascal. Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or giving the user the ability to define both the -iteration step and halting condition (as C), Python's :keyword:`!for` statement +iteration step and halting condition (as C), Python's :keyword:`for` statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence. For example (no pun intended): @@ -60,26 +61,23 @@ they appear in the sequence. For example (no pun intended): >>> # Measure some strings: ... words = ['cat', 'window', 'defenestrate'] >>> for w in words: - ... print(w, len(w)) + ... print w, len(w) ... cat 3 window 6 defenestrate 12 -Code that modifies a collection while iterating over that same collection can -be tricky to get right. Instead, it is usually more straight-forward to loop -over a copy of the collection or to create a new collection:: - - # Strategy: Iterate over a copy - for user, status in users.copy().items(): - if status == 'inactive': - del users[user] +If you need to modify the sequence you are iterating over while inside the loop +(for example to duplicate selected items), it is recommended that you first +make a copy. Iterating over a sequence does not implicitly make a copy. The +slice notation makes this especially convenient:: - # Strategy: Create a new collection - active_users = {} - for user, status in users.items(): - if status == 'active': - active_users[user] = status + >>> for w in words[:]: # Loop over a slice copy of the entire list. + ... if len(w) > 6: + ... words.insert(0, w) + ... + >>> words + ['defenestrate', 'cat', 'window', 'defenestrate'] .. _tut-range: @@ -88,37 +86,30 @@ The :func:`range` Function ========================== If you do need to iterate over a sequence of numbers, the built-in function -:func:`range` comes in handy. It generates arithmetic progressions:: - - >>> for i in range(5): - ... print(i) - ... - 0 - 1 - 2 - 3 - 4 - -The given end point is never part of the generated sequence; ``range(10)`` generates -10 values, the legal indices for items of a sequence of length 10. It -is possible to let the range start at another number, or to specify a different -increment (even negative; sometimes this is called the 'step'):: +:func:`range` comes in handy. It generates lists containing arithmetic +progressions:: - range(5, 10) - 5, 6, 7, 8, 9 + >>> range(10) + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - range(0, 10, 3) - 0, 3, 6, 9 +The given end point is never part of the generated list; ``range(10)`` generates +a list of 10 values, the legal indices for items of a sequence of length 10. It +is possible to let the range start at another number, or to specify a different +increment (even negative; sometimes this is called the 'step'):: - range(-10, -100, -30) - -10, -40, -70 + >>> range(5, 10) + [5, 6, 7, 8, 9] + >>> range(0, 10, 3) + [0, 3, 6, 9] + >>> range(-10, -100, -30) + [-10, -40, -70] To iterate over the indices of a sequence, you can combine :func:`range` and :func:`len` as follows:: >>> a = ['Mary', 'had', 'a', 'little', 'lamb'] >>> for i in range(len(a)): - ... print(i, a[i]) + ... print i, a[i] ... 0 Mary 1 had @@ -129,45 +120,17 @@ To iterate over the indices of a sequence, you can combine :func:`range` and In most such cases, however, it is convenient to use the :func:`enumerate` function, see :ref:`tut-loopidioms`. -A strange thing happens if you just print a range:: - - >>> print(range(10)) - range(0, 10) - -In many ways the object returned by :func:`range` behaves as if it is a list, -but in fact it isn't. It is an object which returns the successive items of -the desired sequence when you iterate over it, but it doesn't really make -the list, thus saving space. - -We say such an object is :term:`iterable`, that is, suitable as a target for -functions and constructs that expect something from which they can -obtain successive items until the supply is exhausted. We have seen that -the :keyword:`for` statement is such a construct, while an example of function -that takes an iterable is :func:`sum`:: - - >>> sum(range(4)) # 0 + 1 + 2 + 3 - 6 - -Later we will see more functions that return iterables and take iterables as -arguments. Lastly, maybe you are curious about how to get a list from a range. -Here is the solution:: - - >>> list(range(4)) - [0, 1, 2, 3] - -In chapter :ref:`tut-structures`, we will discuss in more detail about -:func:`list`. .. _tut-break: -:keyword:`!break` and :keyword:`!continue` Statements, and :keyword:`!else` Clauses on Loops -============================================================================================ +:keyword:`break` and :keyword:`continue` Statements, and :keyword:`else` Clauses on Loops +========================================================================================= The :keyword:`break` statement, like in C, breaks out of the innermost enclosing :keyword:`for` or :keyword:`while` loop. -Loop statements may have an :keyword:`!else` clause; it is executed when the loop -terminates through exhaustion of the iterable (with :keyword:`for`) or when the +Loop statements may have an ``else`` clause; it is executed when the loop +terminates through exhaustion of the list (with :keyword:`for`) or when the condition becomes false (with :keyword:`while`), but not when the loop is terminated by a :keyword:`break` statement. This is exemplified by the following loop, which searches for prime numbers:: @@ -175,11 +138,11 @@ following loop, which searches for prime numbers:: >>> for n in range(2, 10): ... for x in range(2, n): ... if n % x == 0: - ... print(n, 'equals', x, '*', n//x) + ... print n, 'equals', x, '*', n/x ... break ... else: ... # loop fell through without finding a factor - ... print(n, 'is a prime number') + ... print n, 'is a prime number' ... 2 is a prime number 3 is a prime number @@ -194,10 +157,10 @@ following loop, which searches for prime numbers:: the :keyword:`for` loop, **not** the :keyword:`if` statement.) When used with a loop, the ``else`` clause has more in common with the -``else`` clause of a :keyword:`try` statement than it does with that of +``else`` clause of a :keyword:`try` statement than it does that of :keyword:`if` statements: a :keyword:`try` statement's ``else`` clause runs when no exception occurs, and a loop's ``else`` clause runs when no ``break`` -occurs. For more on the :keyword:`!try` statement and exceptions, see +occurs. For more on the :keyword:`try` statement and exceptions, see :ref:`tut-handling`. The :keyword:`continue` statement, also borrowed from C, continues with the next @@ -205,9 +168,9 @@ iteration of the loop:: >>> for num in range(2, 10): ... if num % 2 == 0: - ... print("Found an even number", num) + ... print "Found an even number", num ... continue - ... print("Found a number", num) + ... print "Found a number", num Found an even number 2 Found a number 3 Found an even number 4 @@ -217,10 +180,11 @@ iteration of the loop:: Found an even number 8 Found a number 9 + .. _tut-pass: -:keyword:`!pass` Statements -=========================== +:keyword:`pass` Statements +========================== The :keyword:`pass` statement does nothing. It can be used when a statement is required syntactically but the program requires no action. For example:: @@ -237,7 +201,7 @@ This is commonly used for creating minimal classes:: Another place :keyword:`pass` can be used is as a place-holder for a function or conditional body when you are working on new code, allowing you to keep thinking -at a more abstract level. The :keyword:`!pass` is silently ignored:: +at a more abstract level. The :keyword:`pass` is silently ignored:: >>> def initlog(*args): ... pass # Remember to implement this! @@ -255,9 +219,8 @@ boundary:: ... """Print a Fibonacci series up to n.""" ... a, b = 0, 1 ... while a < n: - ... print(a, end=' ') + ... print a, ... a, b = b, a+b - ... print() ... >>> # Now call the function we just defined: ... fib(2000) @@ -285,11 +248,9 @@ variables of the function. More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the local symbol tables of enclosing functions, then in the global symbol table, and finally in the table -of built-in names. Thus, global variables and variables of enclosing functions -cannot be directly assigned a value within a function (unless, for global -variables, named in a :keyword:`global` statement, or, for variables of enclosing -functions, named in a :keyword:`nonlocal` statement), although they may be -referenced. +of built-in names. Thus, global variables cannot be directly assigned a value +within a function (unless named in a :keyword:`global` statement), although they +may be referenced. The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are @@ -314,10 +275,10 @@ a procedure since it doesn't return a value. In fact, even functions without a :keyword:`return` statement do return a value, albeit a rather boring one. This value is called ``None`` (it's a built-in name). Writing the value ``None`` is normally suppressed by the interpreter if it would be the only value written. -You can see it if you really want to using :func:`print`:: +You can see it if you really want to using :keyword:`print`:: >>> fib(0) - >>> print(fib(0)) + >>> print fib(0) None It is simple to write a function that returns a list of the numbers of the @@ -339,7 +300,7 @@ Fibonacci series, instead of printing it:: This example, as usual, demonstrates some new Python features: * The :keyword:`return` statement returns with a value from a function. - :keyword:`!return` without an expression argument returns ``None``. Falling off + :keyword:`return` without an expression argument returns ``None``. Falling off the end of a function also returns ``None``. * The statement ``result.append(a)`` calls a *method* of the list object @@ -372,17 +333,17 @@ The most useful form is to specify a default value for one or more arguments. This creates a function that can be called with fewer arguments than it is defined to allow. For example:: - def ask_ok(prompt, retries=4, reminder='Please try again!'): + def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): while True: - ok = input(prompt) + ok = raw_input(prompt) if ok in ('y', 'ye', 'yes'): return True if ok in ('n', 'no', 'nop', 'nope'): return False retries = retries - 1 if retries < 0: - raise ValueError('invalid user response') - print(reminder) + raise IOError('refusenik user') + print complaint This function can be called in several ways: @@ -402,7 +363,7 @@ The default values are evaluated at the point of function definition in the i = 5 def f(arg=i): - print(arg) + print arg i = 6 f() @@ -418,9 +379,9 @@ arguments passed to it on subsequent calls:: L.append(a) return L - print(f(1)) - print(f(2)) - print(f(3)) + print f(1) + print f(2) + print f(3) This will print :: @@ -447,10 +408,10 @@ Functions can also be called using :term:`keyword arguments <keyword argument>` of the form ``kwarg=value``. For instance, the following function:: def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'): - print("-- This parrot wouldn't", action, end=' ') - print("if you put", voltage, "volts through it.") - print("-- Lovely plumage, the", type) - print("-- It's", state, "!") + print "-- This parrot wouldn't", action, + print "if you put", voltage, "volts through it." + print "-- Lovely plumage, the", type + print "-- It's", state, "!" accepts one required argument (``voltage``) and three optional arguments (``state``, ``action``, and ``type``). This function can be called in any @@ -490,24 +451,25 @@ When a final formal parameter of the form ``**name`` is present, it receives a dictionary (see :ref:`typesmapping`) containing all keyword arguments except for those corresponding to a formal parameter. This may be combined with a formal parameter of the form ``*name`` (described in the next subsection) which -receives a :ref:`tuple <tut-tuples>` containing the positional -arguments beyond the formal parameter list. (``*name`` must occur -before ``**name``.) For example, if we define a function like this:: +receives a tuple containing the positional arguments beyond the formal parameter +list. (``*name`` must occur before ``**name``.) For example, if we define a +function like this:: def cheeseshop(kind, *arguments, **keywords): - print("-- Do you have any", kind, "?") - print("-- I'm sorry, we're all out of", kind) + print "-- Do you have any", kind, "?" + print "-- I'm sorry, we're all out of", kind for arg in arguments: - print(arg) - print("-" * 40) - for kw in keywords: - print(kw, ":", keywords[kw]) + print arg + print "-" * 40 + keys = sorted(keywords.keys()) + for kw in keys: + print kw, ":", keywords[kw] It could be called like this:: cheeseshop("Limburger", "It's very runny, sir.", "It's really very, VERY runny, sir.", - shopkeeper="Michael Palin", + shopkeeper='Michael Palin', client="John Cleese", sketch="Cheese Shop Sketch") @@ -520,183 +482,13 @@ and of course it would print: It's very runny, sir. It's really very, VERY runny, sir. ---------------------------------------- - shopkeeper : Michael Palin client : John Cleese + shopkeeper : Michael Palin sketch : Cheese Shop Sketch -Note that the order in which the keyword arguments are printed is guaranteed -to match the order in which they were provided in the function call. - -Special parameters ------------------- - -By default, arguments may be passed to a Python function either by position -or explicitly by keyword. For readability and performance, it makes sense to -restrict the way arguments can be passed so that a developer need only look -at the function definition to determine if items are passed by position, by -position or keyword, or by keyword. - -A function definition may look like: - -.. code-block:: none - - def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2): - ----------- ---------- ---------- - | | | - | Positional or keyword | - | - Keyword only - -- Positional only - -where ``/`` and ``*`` are optional. If used, these symbols indicate the kind of -parameter by how the arguments may be passed to the function: -positional-only, positional-or-keyword, and keyword-only. Keyword parameters -are also referred to as named parameters. - -------------------------------- -Positional-or-Keyword Arguments -------------------------------- - -If ``/`` and ``*`` are not present in the function definition, arguments may -be passed to a function by position or by keyword. - --------------------------- -Positional-Only Parameters --------------------------- - -Looking at this in a bit more detail, it is possible to mark certain parameters -as *positional-only*. If *positional-only*, the parameters' order matters, and -the parameters cannot be passed by keyword. Positional-only parameters are -placed before a ``/`` (forward-slash). The ``/`` is used to logically -separate the positional-only parameters from the rest of the parameters. -If there is no ``/`` in the function definition, there are no positional-only -parameters. - -Parameters following the ``/`` may be *positional-or-keyword* or *keyword-only*. - ----------------------- -Keyword-Only Arguments ----------------------- - -To mark parameters as *keyword-only*, indicating the parameters must be passed -by keyword argument, place an ``*`` in the arguments list just before the first -*keyword-only* parameter. - ------------------ -Function Examples ------------------ - -Consider the following example function definitions paying close attention to the -markers ``/`` and ``*``:: - - >>> def standard_arg(arg): - ... print(arg) - ... - >>> def pos_only_arg(arg, /): - ... print(arg) - ... - >>> def kwd_only_arg(*, arg): - ... print(arg) - ... - >>> def combined_example(pos_only, /, standard, *, kwd_only): - ... print(pos_only, standard, kwd_only) - - -The first function definition, ``standard_arg``, the most familiar form, -places no restrictions on the calling convention and arguments may be -passed by position or keyword:: - - >>> standard_arg(2) - 2 - - >>> standard_arg(arg=2) - 2 - -The second function ``pos_only_arg`` is restricted to only use positional -parameters as there is a ``/`` in the function definition:: - - >>> pos_only_arg(1) - 1 - - >>> pos_only_arg(arg=1) - Traceback (most recent call last): - File "<stdin>", line 1, in <module> - TypeError: pos_only_arg() got an unexpected keyword argument 'arg' - -The third function ``kwd_only_args`` only allows keyword arguments as indicated -by a ``*`` in the function definition:: - - >>> kwd_only_arg(3) - Traceback (most recent call last): - File "<stdin>", line 1, in <module> - TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given - - >>> kwd_only_arg(arg=3) - 3 - -And the last uses all three calling conventions in the same function -definition:: - - >>> combined_example(1, 2, 3) - Traceback (most recent call last): - File "<stdin>", line 1, in <module> - TypeError: combined_example() takes 2 positional arguments but 3 were given - - >>> combined_example(1, 2, kwd_only=3) - 1 2 3 - - >>> combined_example(1, standard=2, kwd_only=3) - 1 2 3 - - >>> combined_example(pos_only=1, standard=2, kwd_only=3) - Traceback (most recent call last): - File "<stdin>", line 1, in <module> - TypeError: combined_example() got an unexpected keyword argument 'pos_only' - - -Finally, consider this function definition which has a potential collision between the positional argument ``name`` and ``**kwds`` which has ``name`` as a key:: - - def foo(name, **kwds): - return 'name' in kwds - -There is no possible call that will make it return ``True`` as the keyword ``'name'`` -will always to bind to the first parameter. For example:: - - >>> foo(1, **{'name': 2}) - Traceback (most recent call last): - File "<stdin>", line 1, in <module> - TypeError: foo() got multiple values for argument 'name' - >>> - -But using ``/`` (positional only arguments), it is possible since it allows ``name`` as a positional argument and ``'name'`` as a key in the keyword arguments:: - - def foo(name, /, **kwds): - return 'name' in kwds - >>> foo(1, **{'name': 2}) - True - -In other words, the names of positional-only parameters can be used in -``**kwds`` without ambiguity. - ------ -Recap ------ - -The use case will determine which parameters to use in the function definition:: - - def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2): - -As guidance: - -* Use positional-only if you want the name of the parameters to not be - available to the user. This is useful when parameter names have no real - meaning, if you want to enforce the order of the arguments when the function - is called or if you need to take some positional parameters and arbitrary - keywords. -* Use keyword-only when names have meaning and the function definition is - more understandable by being explicit with names or you want to prevent - users relying on the position of the argument being passed. -* For an API, use positional-only to prevent breaking API changes - if the parameter's name is modified in the future. +Note that the list of keyword argument names is created by sorting the result +of the keywords dictionary's ``keys()`` method before printing its contents; +if this is not done, the order in which the arguments are printed is undefined. .. _tut-arbitraryargs: @@ -704,7 +496,7 @@ Arbitrary Argument Lists ------------------------ .. index:: - single: * (asterisk); in function calls + statement: * Finally, the least frequently used option is to specify that a function can be called with an arbitrary number of arguments. These arguments will be wrapped @@ -715,20 +507,6 @@ zero or more normal arguments may occur. :: file.write(separator.join(args)) -Normally, these ``variadic`` arguments will be last in the list of formal -parameters, because they scoop up all remaining input arguments that are -passed to the function. Any formal parameters which occur after the ``*args`` -parameter are 'keyword-only' arguments, meaning that they can only be used as -keywords rather than positional arguments. :: - - >>> def concat(*args, sep="/"): - ... return sep.join(args) - ... - >>> concat("earth", "mars", "venus") - 'earth/mars/venus' - >>> concat("earth", "mars", "venus", sep=".") - 'earth.mars.venus' - .. _tut-unpacking-arguments: Unpacking Argument Lists @@ -741,22 +519,22 @@ arguments. For instance, the built-in :func:`range` function expects separate function call with the ``*``\ -operator to unpack the arguments out of a list or tuple:: - >>> list(range(3, 6)) # normal call with separate arguments + >>> range(3, 6) # normal call with separate arguments [3, 4, 5] >>> args = [3, 6] - >>> list(range(*args)) # call with arguments unpacked from a list + >>> range(*args) # call with arguments unpacked from a list [3, 4, 5] .. index:: - single: **; in function calls + statement: ** -In the same fashion, dictionaries can deliver keyword arguments with the -``**``\ -operator:: +In the same fashion, dictionaries can deliver keyword arguments with the ``**``\ +-operator:: >>> def parrot(voltage, state='a stiff', action='voom'): - ... print("-- This parrot wouldn't", action, end=' ') - ... print("if you put", voltage, "volts through it.", end=' ') - ... print("E's", state, "!") + ... print "-- This parrot wouldn't", action, + ... print "if you put", voltage, "volts through it.", + ... print "E's", state, "!" ... >>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"} >>> parrot(**d) @@ -804,7 +582,7 @@ Documentation Strings single: documentation strings single: strings, documentation -Here are some conventions about the content and formatting of documentation +There are emerging conventions about the content and formatting of documentation strings. The first line should always be a short, concise summary of the object's @@ -839,46 +617,12 @@ Here is an example of a multi-line docstring:: ... """ ... pass ... - >>> print(my_function.__doc__) + >>> print my_function.__doc__ Do nothing, but document it. No, really, it doesn't do anything. -.. _tut-annotations: - -Function Annotations --------------------- - -.. sectionauthor:: Zachary Ware <zachary.ware@gmail.com> -.. index:: - pair: function; annotations - single: ->; function annotations - single: : (colon); function annotations - -:ref:`Function annotations <function>` are completely optional metadata -information about the types used by user-defined functions (see :pep:`3107` and -:pep:`484` for more information). - -:term:`Annotations <function annotation>` are stored in the :attr:`__annotations__` -attribute of the function as a dictionary and have no effect on any other part of the -function. Parameter annotations are defined by a colon after the parameter name, followed -by an expression evaluating to the value of the annotation. Return annotations are -defined by a literal ``->``, followed by an expression, between the parameter -list and the colon denoting the end of the :keyword:`def` statement. The -following example has a positional argument, a keyword argument, and the return -value annotated:: - - >>> def f(ham: str, eggs: str = 'eggs') -> str: - ... print("Annotations:", f.__annotations__) - ... print("Arguments:", ham, eggs) - ... return ham + ' and ' + eggs - ... - >>> f('spam') - Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>} - Arguments: spam eggs - 'spam and eggs' - .. _tut-codingstyle: Intermezzo: Coding Style @@ -920,17 +664,12 @@ extracted for you: bracketing constructs: ``a = f(1, 2) + g(3, 4)``. * Name your classes and functions consistently; the convention is to use - ``UpperCamelCase`` for classes and ``lowercase_with_underscores`` for functions + ``CamelCase`` for classes and ``lower_case_with_underscores`` for functions and methods. Always use ``self`` as the name for the first method argument (see :ref:`tut-firstclasses` for more on classes and methods). * Don't use fancy encodings if your code is meant to be used in international - environments. Python's default, UTF-8, or even plain ASCII work best in any - case. - -* Likewise, don't use non-ASCII characters in identifiers if there is only the - slightest chance people speaking a different language will read or maintain - the code. + environments. Plain ASCII works best in any case. .. rubric:: Footnotes @@ -938,3 +677,4 @@ extracted for you: .. [#] Actually, *call by object reference* would be a better description, since if a mutable object is passed, the caller will see any changes the callee makes to it (items inserted into a list). + diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index 2f7afb0..4e60e32 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -7,6 +7,7 @@ Data Structures This chapter describes some things you've learned about already in more detail, and adds some new things as well. + .. _tut-morelists: More on Lists @@ -19,14 +20,14 @@ objects: .. method:: list.append(x) :noindex: - Add an item to the end of the list. Equivalent to ``a[len(a):] = [x]``. + Add an item to the end of the list; equivalent to ``a[len(a):] = [x]``. -.. method:: list.extend(iterable) +.. method:: list.extend(L) :noindex: - Extend the list by appending all the items from the iterable. Equivalent to - ``a[len(a):] = iterable``. + Extend the list by appending all the items in the given list; equivalent to + ``a[len(a):] = L``. .. method:: list.insert(i, x) @@ -40,8 +41,8 @@ objects: .. method:: list.remove(x) :noindex: - Remove the first item from the list whose value is equal to *x*. It raises a - :exc:`ValueError` if there is no such item. + Remove the first item from the list whose value is *x*. It is an error if there + is no such item. .. method:: list.pop([i]) @@ -54,22 +55,11 @@ objects: will see this notation frequently in the Python Library Reference.) -.. method:: list.clear() - :noindex: - - Remove all items from the list. Equivalent to ``del a[:]``. - - -.. method:: list.index(x[, start[, end]]) +.. method:: list.index(x) :noindex: - Return zero-based index in the list of the first item whose value is equal to *x*. - Raises a :exc:`ValueError` if there is no such item. - - The optional arguments *start* and *end* are interpreted as in the slice - notation and are used to limit the search to a particular subsequence of - the list. The returned index is computed relative to the beginning of the full - sequence rather than the *start* argument. + Return the index in the list of the first item whose value is *x*. It is an + error if there is no such item. .. method:: list.count(x) @@ -78,7 +68,7 @@ objects: Return the number of times *x* appears in the list. -.. method:: list.sort(key=None, reverse=False) +.. method:: list.sort(cmp=None, key=None, reverse=False) :noindex: Sort the items of the list in place (the arguments can be used for sort @@ -88,50 +78,38 @@ objects: .. method:: list.reverse() :noindex: - Reverse the elements of the list in place. - - -.. method:: list.copy() - :noindex: - - Return a shallow copy of the list. Equivalent to ``a[:]``. - + Reverse the elements of the list, in place. An example that uses most of the list methods:: - >>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana'] - >>> fruits.count('apple') - 2 - >>> fruits.count('tangerine') - 0 - >>> fruits.index('banana') - 3 - >>> fruits.index('banana', 4) # Find next banana starting a position 4 - 6 - >>> fruits.reverse() - >>> fruits - ['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange'] - >>> fruits.append('grape') - >>> fruits - ['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape'] - >>> fruits.sort() - >>> fruits - ['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear'] - >>> fruits.pop() - 'pear' + >>> a = [66.25, 333, 333, 1, 1234.5] + >>> print a.count(333), a.count(66.25), a.count('x') + 2 1 0 + >>> a.insert(2, -1) + >>> a.append(333) + >>> a + [66.25, 333, -1, 333, 1, 1234.5, 333] + >>> a.index(333) + 1 + >>> a.remove(333) + >>> a + [66.25, -1, 333, 1, 1234.5, 333] + >>> a.reverse() + >>> a + [333, 1234.5, 1, 333, -1, 66.25] + >>> a.sort() + >>> a + [-1, 1, 66.25, 333, 333, 1234.5] + >>> a.pop() + 1234.5 + >>> a + [-1, 1, 66.25, 333, 333] You might have noticed that methods like ``insert``, ``remove`` or ``sort`` that only modify the list have no return value printed -- they return the default -``None``. [1]_ This is a design principle for all mutable data structures in +``None``. This is a design principle for all mutable data structures in Python. -Another thing you might notice is that not all data can be sorted or -compared. For instance, ``[None, 'hello', 10]`` doesn't sort because -integers can't be compared to strings and *None* can't be compared to -other types. Also, there are some types that don't have a defined -ordering relation. For example, ``3+4j < 5+7j`` isn't a valid -comparison. - .. _tut-lists-as-stacks: @@ -191,6 +169,76 @@ have fast appends and pops from both ends. For example:: deque(['Michael', 'Terry', 'Graham']) +.. _tut-functional: + +Functional Programming Tools +---------------------------- + +There are three built-in functions that are very useful when used with lists: +:func:`filter`, :func:`map`, and :func:`reduce`. + +``filter(function, sequence)`` returns a sequence consisting of those items from +the sequence for which ``function(item)`` is true. If *sequence* is a +:class:`str`, :class:`unicode` or :class:`tuple`, the result will be of the +same type; otherwise, it is always a :class:`list`. For example, to compute a +sequence of numbers divisible by 3 or 5:: + + >>> def f(x): return x % 3 == 0 or x % 5 == 0 + ... + >>> filter(f, range(2, 25)) + [3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24] + +``map(function, sequence)`` calls ``function(item)`` for each of the sequence's +items and returns a list of the return values. For example, to compute some +cubes:: + + >>> def cube(x): return x*x*x + ... + >>> map(cube, range(1, 11)) + [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000] + +More than one sequence may be passed; the function must then have as many +arguments as there are sequences and is called with the corresponding item from +each sequence (or ``None`` if some sequence is shorter than another). For +example:: + + >>> seq = range(8) + >>> def add(x, y): return x+y + ... + >>> map(add, seq, seq) + [0, 2, 4, 6, 8, 10, 12, 14] + +``reduce(function, sequence)`` returns a single value constructed by calling the +binary function *function* on the first two items of the sequence, then on the +result and the next item, and so on. For example, to compute the sum of the +numbers 1 through 10:: + + >>> def add(x,y): return x+y + ... + >>> reduce(add, range(1, 11)) + 55 + +If there's only one item in the sequence, its value is returned; if the sequence +is empty, an exception is raised. + +A third argument can be passed to indicate the starting value. In this case the +starting value is returned for an empty sequence, and the function is first +applied to the starting value and the first sequence item, then to the result +and the next item, and so on. For example, :: + + >>> def sum(seq): + ... def add(x,y): return x+y + ... return reduce(add, seq, 0) + ... + >>> sum(range(1, 11)) + 55 + >>> sum([]) + 0 + +Don't use this example's definition of :func:`sum`: since summing numbers is +such a common need, a built-in function ``sum(sequence)`` is already provided, +and works exactly like this. + .. _tut-listcomps: List Comprehensions @@ -210,29 +258,24 @@ For example, assume we want to create a list of squares, like:: >>> squares [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] -Note that this creates (or overwrites) a variable named ``x`` that still exists -after the loop completes. We can calculate the list of squares without any -side effects using:: - - squares = list(map(lambda x: x**2, range(10))) - -or, equivalently:: +We can obtain the same result with:: squares = [x**2 for x in range(10)] -which is more concise and readable. +This is also equivalent to ``squares = map(lambda x: x**2, range(10))``, +but it's more concise and readable. A list comprehension consists of brackets containing an expression followed -by a :keyword:`!for` clause, then zero or more :keyword:`!for` or :keyword:`!if` +by a :keyword:`for` clause, then zero or more :keyword:`for` or :keyword:`if` clauses. The result will be a new list resulting from evaluating the expression -in the context of the :keyword:`!for` and :keyword:`!if` clauses which follow it. +in the context of the :keyword:`for` and :keyword:`if` clauses which follow it. For example, this listcomp combines the elements of two lists if they are not equal:: >>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y] [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)] -and it's equivalent to:: +and it's equivalent to: >>> combs = [] >>> for x in [1,2,3]: @@ -283,8 +326,9 @@ List comprehensions can contain complex expressions and nested functions:: >>> [str(round(pi, i)) for i in range(1, 6)] ['3.1', '3.14', '3.142', '3.1416', '3.14159'] + Nested List Comprehensions --------------------------- +'''''''''''''''''''''''''' The initial expression in a list comprehension can be any arbitrary expression, including another list comprehension. @@ -327,22 +371,23 @@ which, in turn, is the same as:: >>> transposed [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]] + In the real world, you should prefer built-in functions to complex flow statements. The :func:`zip` function would do a great job for this use case:: - >>> list(zip(*matrix)) + >>> zip(*matrix) [(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)] See :ref:`tut-unpacking-arguments` for details on the asterisk in this line. .. _tut-del: -The :keyword:`!del` statement -============================= +The :keyword:`del` statement +============================ There is a way to remove an item from a list given its index instead of its value: the :keyword:`del` statement. This differs from the :meth:`pop` method -which returns a value. The :keyword:`!del` statement can also be used to remove +which returns a value. The :keyword:`del` statement can also be used to remove slices from a list or clear the entire list (which we did earlier by assignment of an empty list to the slice). For example:: @@ -435,8 +480,8 @@ The reverse operation is also possible:: >>> x, y, z = t This is called, appropriately enough, *sequence unpacking* and works for any -sequence on the right-hand side. Sequence unpacking requires that there are as -many variables on the left side of the equals sign as there are elements in the +sequence on the right-hand side. Sequence unpacking requires the list of +variables on the left to have the same number of elements as the length of the sequence. Note that multiple assignment is really just a combination of tuple packing and sequence unpacking. @@ -457,12 +502,13 @@ empty dictionary, a data structure that we discuss in the next section. Here is a brief demonstration:: - >>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'} - >>> print(basket) # show that duplicates have been removed - {'orange', 'banana', 'pear', 'apple'} - >>> 'orange' in basket # fast membership testing + >>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] + >>> fruit = set(basket) # create a set without duplicates + >>> fruit + set(['orange', 'pear', 'apple', 'banana']) + >>> 'orange' in fruit # fast membership testing True - >>> 'crabgrass' in basket + >>> 'crabgrass' in fruit False >>> # Demonstrate set operations on unique letters from two words @@ -470,22 +516,22 @@ Here is a brief demonstration:: >>> a = set('abracadabra') >>> b = set('alacazam') >>> a # unique letters in a - {'a', 'r', 'b', 'c', 'd'} + set(['a', 'r', 'b', 'c', 'd']) >>> a - b # letters in a but not in b - {'r', 'd', 'b'} - >>> a | b # letters in a or b or both - {'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'} + set(['r', 'd', 'b']) + >>> a | b # letters in either a or b + set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l']) >>> a & b # letters in both a and b - {'a', 'c'} + set(['a', 'c']) >>> a ^ b # letters in a or b but not both - {'r', 'd', 'b', 'm', 'z', 'l'} + set(['r', 'd', 'b', 'm', 'z', 'l']) Similarly to :ref:`list comprehensions <tut-listcomps>`, set comprehensions are also supported:: >>> a = {x for x in 'abracadabra' if x not in 'abc'} >>> a - {'r', 'd'} + set(['r', 'd']) .. _tut-dictionaries: @@ -504,7 +550,7 @@ You can't use lists as keys, since lists can be modified in place using index assignments, slice assignments, or methods like :meth:`append` and :meth:`extend`. -It is best to think of a dictionary as a set of *key: value* pairs, +It is best to think of a dictionary as an unordered set of *key: value* pairs, with the requirement that the keys are unique (within one dictionary). A pair of braces creates an empty dictionary: ``{}``. Placing a comma-separated list of key:value pairs within the braces adds initial key:value pairs to the @@ -516,9 +562,9 @@ pair with ``del``. If you store using a key that is already in use, the old value associated with that key is forgotten. It is an error to extract a value using a non-existent key. -Performing ``list(d)`` on a dictionary returns a list of all the keys -used in the dictionary, in insertion order (if you want it sorted, just use -``sorted(d)`` instead). To check whether a single key is in the +The :meth:`keys` method of a dictionary object returns a list of all the keys +used in the dictionary, in arbitrary order (if you want it sorted, just apply +the :func:`sorted` function to it). To check whether a single key is in the dictionary, use the :keyword:`in` keyword. Here is a small example using a dictionary:: @@ -526,27 +572,23 @@ Here is a small example using a dictionary:: >>> tel = {'jack': 4098, 'sape': 4139} >>> tel['guido'] = 4127 >>> tel - {'jack': 4098, 'sape': 4139, 'guido': 4127} + {'sape': 4139, 'guido': 4127, 'jack': 4098} >>> tel['jack'] 4098 >>> del tel['sape'] >>> tel['irv'] = 4127 >>> tel - {'jack': 4098, 'guido': 4127, 'irv': 4127} - >>> list(tel) - ['jack', 'guido', 'irv'] - >>> sorted(tel) + {'guido': 4127, 'irv': 4127, 'jack': 4098} + >>> tel.keys() ['guido', 'irv', 'jack'] >>> 'guido' in tel True - >>> 'jack' not in tel - False The :func:`dict` constructor builds dictionaries directly from sequences of key-value pairs:: >>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]) - {'sape': 4139, 'guido': 4127, 'jack': 4098} + {'sape': 4139, 'jack': 4098, 'guido': 4127} In addition, dict comprehensions can be used to create dictionaries from arbitrary key and value expressions:: @@ -558,7 +600,7 @@ When the keys are simple strings, it is sometimes easier to specify pairs using keyword arguments:: >>> dict(sape=4139, guido=4127, jack=4098) - {'sape': 4139, 'guido': 4127, 'jack': 4098} + {'sape': 4139, 'jack': 4098, 'guido': 4127} .. _tut-loopidioms: @@ -566,21 +608,11 @@ keyword arguments:: Looping Techniques ================== -When looping through dictionaries, the key and corresponding value can be -retrieved at the same time using the :meth:`items` method. :: - - >>> knights = {'gallahad': 'the pure', 'robin': 'the brave'} - >>> for k, v in knights.items(): - ... print(k, v) - ... - gallahad the pure - robin the brave - When looping through a sequence, the position index and corresponding value can be retrieved at the same time using the :func:`enumerate` function. :: >>> for i, v in enumerate(['tic', 'tac', 'toe']): - ... print(i, v) + ... print i, v ... 0 tic 1 tac @@ -592,7 +624,7 @@ with the :func:`zip` function. :: >>> questions = ['name', 'quest', 'favorite color'] >>> answers = ['lancelot', 'the holy grail', 'blue'] >>> for q, a in zip(questions, answers): - ... print('What is your {0}? It is {1}.'.format(q, a)) + ... print 'What is your {0}? It is {1}.'.format(q, a) ... What is your name? It is lancelot. What is your quest? It is the holy grail. @@ -601,8 +633,8 @@ with the :func:`zip` function. :: To loop over a sequence in reverse, first specify the sequence in a forward direction and then call the :func:`reversed` function. :: - >>> for i in reversed(range(1, 10, 2)): - ... print(i) + >>> for i in reversed(xrange(1,10,2)): + ... print i ... 9 7 @@ -615,13 +647,23 @@ returns a new sorted list while leaving the source unaltered. :: >>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] >>> for f in sorted(set(basket)): - ... print(f) + ... print f ... apple banana orange pear +When looping through dictionaries, the key and corresponding value can be +retrieved at the same time using the :meth:`iteritems` method. :: + + >>> knights = {'gallahad': 'the pure', 'robin': 'the brave'} + >>> for k, v in knights.iteritems(): + ... print k, v + ... + gallahad the pure + robin the brave + It is sometimes tempting to change a list while you are looping over it; however, it is often simpler and safer to create a new list instead. :: @@ -675,27 +717,28 @@ to a variable. For example, :: >>> non_null 'Trondheim' -Note that in Python, unlike C, assignment inside expressions must be done -explicitly with the walrus operator ``:=``. This avoids a common class of -problems encountered in C programs: typing ``=`` in an expression when ``==`` -was intended. +Note that in Python, unlike C, assignment cannot occur inside expressions. C +programmers may grumble about this, but it avoids a common class of problems +encountered in C programs: typing ``=`` in an expression when ``==`` was +intended. .. _tut-comparing: Comparing Sequences and Other Types =================================== -Sequence objects typically may be compared to other objects with the same sequence -type. The comparison uses *lexicographical* ordering: first the first two -items are compared, and if they differ this determines the outcome of the -comparison; if they are equal, the next two items are compared, and so on, until -either sequence is exhausted. If two items to be compared are themselves -sequences of the same type, the lexicographical comparison is carried out -recursively. If all items of two sequences compare equal, the sequences are -considered equal. If one sequence is an initial sub-sequence of the other, the -shorter sequence is the smaller (lesser) one. Lexicographical ordering for -strings uses the Unicode code point number to order individual characters. -Some examples of comparisons between sequences of the same type:: + +Sequence objects may be compared to other objects with the same sequence type. +The comparison uses *lexicographical* ordering: first the first two items are +compared, and if they differ this determines the outcome of the comparison; if +they are equal, the next two items are compared, and so on, until either +sequence is exhausted. If two items to be compared are themselves sequences of +the same type, the lexicographical comparison is carried out recursively. If +all items of two sequences compare equal, the sequences are considered equal. +If one sequence is an initial sub-sequence of the other, the shorter sequence is +the smaller (lesser) one. Lexicographical ordering for strings uses the ASCII +ordering for individual characters. Some examples of comparisons between +sequences of the same type:: (1, 2, 3) < (1, 2, 4) [1, 2, 3] < [1, 2, 4] @@ -705,14 +748,15 @@ Some examples of comparisons between sequences of the same type:: (1, 2, 3) == (1.0, 2.0, 3.0) (1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4) -Note that comparing objects of different types with ``<`` or ``>`` is legal -provided that the objects have appropriate comparison methods. For example, -mixed numeric types are compared according to their numeric value, so 0 equals -0.0, etc. Otherwise, rather than providing an arbitrary ordering, the -interpreter will raise a :exc:`TypeError` exception. +Note that comparing objects of different types is legal. The outcome is +deterministic but arbitrary: the types are ordered by their name. Thus, a list +is always smaller than a string, a string is always smaller than a tuple, etc. +[#]_ Mixed numeric types are compared according to their numeric value, so 0 +equals 0.0, etc. .. rubric:: Footnotes -.. [1] Other languages may return the mutated object, which allows method - chaining, such as ``d->insert("a")->remove("b")->sort();``. +.. [#] The rules for comparing objects of different types should not be relied upon; + they may change in a future version of the language. + diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst index 8f86eca..247dda7 100644 --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -17,16 +17,16 @@ Syntax Errors Syntax errors, also known as parsing errors, are perhaps the most common kind of complaint you get while you are still learning Python:: - >>> while True print('Hello world') + >>> while True print 'Hello world' File "<stdin>", line 1 - while True print('Hello world') + while True print 'Hello world' ^ SyntaxError: invalid syntax The parser repeats the offending line and displays a little 'arrow' pointing at the earliest point in the line where the error was detected. The error is caused by (or at least detected at) the token *preceding* the arrow: in the -example, the error is detected at the function :func:`print`, since a colon +example, the error is detected at the keyword :keyword:`print`, since a colon (``':'``) is missing before it. File name and line number are printed so you know where to look in case the input came from a script. @@ -45,7 +45,7 @@ programs, however, and result in error messages as shown here:: >>> 10 * (1/0) Traceback (most recent call last): File "<stdin>", line 1, in <module> - ZeroDivisionError: division by zero + ZeroDivisionError: integer division or modulo by zero >>> 4 + spam*3 Traceback (most recent call last): File "<stdin>", line 1, in <module> @@ -53,7 +53,7 @@ programs, however, and result in error messages as shown here:: >>> '2' + 2 Traceback (most recent call last): File "<stdin>", line 1, in <module> - TypeError: Can't convert 'int' object to str implicitly + TypeError: cannot concatenate 'str' and 'int' objects The last line of the error message indicates what happened. Exceptions come in different types, and the type is printed as part of the message: the types in @@ -87,10 +87,10 @@ is signalled by raising the :exc:`KeyboardInterrupt` exception. :: >>> while True: ... try: - ... x = int(input("Please enter a number: ")) + ... x = int(raw_input("Please enter a number: ")) ... break ... except ValueError: - ... print("Oops! That was no valid number. Try again...") + ... print "Oops! That was no valid number. Try again..." ... The :keyword:`try` statement works as follows. @@ -114,38 +114,19 @@ The :keyword:`try` statement works as follows. A :keyword:`try` statement may have more than one except clause, to specify handlers for different exceptions. At most one handler will be executed. Handlers only handle exceptions that occur in the corresponding try clause, not -in other handlers of the same :keyword:`!try` statement. An except clause may +in other handlers of the same :keyword:`try` statement. An except clause may name multiple exceptions as a parenthesized tuple, for example:: ... except (RuntimeError, TypeError, NameError): ... pass -A class in an :keyword:`except` clause is compatible with an exception if it is -the same class or a base class thereof (but not the other way around --- an -except clause listing a derived class is not compatible with a base class). For -example, the following code will print B, C, D in that order:: - - class B(Exception): - pass - - class C(B): - pass - - class D(C): - pass - - for cls in [B, C, D]: - try: - raise cls() - except D: - print("D") - except C: - print("C") - except B: - print("B") - -Note that if the except clauses were reversed (with ``except B`` first), it -would have printed B, B, B --- the first matching except clause is triggered. +Note that the parentheses around this tuple are required, because +``except ValueError, e:`` was the syntax used for what is normally +written as ``except ValueError as e:`` in modern Python (described +below). The old syntax is still supported for backwards compatibility. +This means ``except RuntimeError, TypeError`` is not equivalent to +``except (RuntimeError, TypeError):`` but to ``except RuntimeError as +TypeError:`` which is not what you want. The last except clause may omit the exception name(s), to serve as a wildcard. Use this with extreme caution, since it is easy to mask a real programming error @@ -158,12 +139,12 @@ the exception (allowing a caller to handle the exception as well):: f = open('myfile.txt') s = f.readline() i = int(s.strip()) - except OSError as err: - print("OS error: {0}".format(err)) + except IOError as e: + print "I/O error({0}): {1}".format(e.errno, e.strerror) except ValueError: - print("Could not convert data to an integer.") + print "Could not convert data to an integer." except: - print("Unexpected error:", sys.exc_info()[0]) + print "Unexpected error:", sys.exc_info()[0] raise The :keyword:`try` ... :keyword:`except` statement has an optional *else @@ -174,46 +155,47 @@ example:: for arg in sys.argv[1:]: try: f = open(arg, 'r') - except OSError: - print('cannot open', arg) + except IOError: + print 'cannot open', arg else: - print(arg, 'has', len(f.readlines()), 'lines') + print arg, 'has', len(f.readlines()), 'lines' f.close() -The use of the :keyword:`!else` clause is better than adding additional code to +The use of the :keyword:`else` clause is better than adding additional code to the :keyword:`try` clause because it avoids accidentally catching an exception -that wasn't raised by the code being protected by the :keyword:`!try` ... -:keyword:`!except` statement. +that wasn't raised by the code being protected by the :keyword:`try` ... +:keyword:`except` statement. When an exception occurs, it may have an associated value, also known as the exception's *argument*. The presence and type of the argument depend on the exception type. -The except clause may specify a variable after the exception name. The -variable is bound to an exception instance with the arguments stored in +The except clause may specify a variable after the exception name (or tuple). +The variable is bound to an exception instance with the arguments stored in ``instance.args``. For convenience, the exception instance defines :meth:`__str__` so the arguments can be printed directly without having to -reference ``.args``. One may also instantiate an exception first before -raising it and add any attributes to it as desired. :: +reference ``.args``. + +One may also instantiate an exception first before raising it and add any +attributes to it as desired. :: >>> try: ... raise Exception('spam', 'eggs') ... except Exception as inst: - ... print(type(inst)) # the exception instance - ... print(inst.args) # arguments stored in .args - ... print(inst) # __str__ allows args to be printed directly, - ... # but may be overridden in exception subclasses - ... x, y = inst.args # unpack args - ... print('x =', x) - ... print('y =', y) + ... print type(inst) # the exception instance + ... print inst.args # arguments stored in .args + ... print inst # __str__ allows args to be printed directly + ... x, y = inst.args + ... print 'x =', x + ... print 'y =', y ... - <class 'Exception'> + <type 'exceptions.Exception'> ('spam', 'eggs') ('spam', 'eggs') x = spam y = eggs -If an exception has arguments, they are printed as the last part ('detail') of +If an exception has an argument, it is printed as the last part ('detail') of the message for unhandled exceptions. Exception handlers don't just handle exceptions if they occur immediately in the @@ -225,10 +207,10 @@ indirectly) in the try clause. For example:: ... >>> try: ... this_fails() - ... except ZeroDivisionError as err: - ... print('Handling run-time error:', err) + ... except ZeroDivisionError as detail: + ... print 'Handling run-time error:', detail ... - Handling run-time error: division by zero + Handling run-time error: integer division or modulo by zero .. _tut-raising: @@ -246,10 +228,7 @@ exception to occur. For example:: The sole argument to :keyword:`raise` indicates the exception to be raised. This must be either an exception instance or an exception class (a class that -derives from :class:`Exception`). If an exception class is passed, it will -be implicitly instantiated by calling its constructor with no arguments:: - - raise ValueError # shorthand for 'raise ValueError()' +derives from :class:`Exception`). If you need to determine whether an exception was raised but don't intend to handle it, a simpler form of the :keyword:`raise` statement allows you to @@ -258,7 +237,7 @@ re-raise the exception:: >>> try: ... raise NameError('HiThere') ... except NameError: - ... print('An exception flew by!') + ... print 'An exception flew by!' ... raise ... An exception flew by! @@ -267,53 +246,6 @@ re-raise the exception:: NameError: HiThere -.. _tut-exception-chaining: - -Exception Chaining -================== - -The :keyword:`raise` statement allows an optional :keyword:`from` which enables -chaining exceptions by setting the ``__cause__`` attribute of the raised -exception. For example:: - - raise RuntimeError from OSError - -This can be useful when you are transforming exceptions. For example:: - - >>> def func(): - ... raise IOError - ... - >>> try: - ... func() - ... except IOError as exc: - ... raise RuntimeError('Failed to open database') from exc - ... - Traceback (most recent call last): - File "<stdin>", line 2, in <module> - File "<stdin>", line 2, in func - OSError - <BLANKLINE> - The above exception was the direct cause of the following exception: - <BLANKLINE> - Traceback (most recent call last): - File "<stdin>", line 4, in <module> - RuntimeError - -The expression following the :keyword:`from` must be either an exception or -``None``. Exception chaining happens automatically when an exception is raised -inside an exception handler or :keyword:`finally` section. Exception chaining -can be disabled by using ``from None`` idiom: - - >>> try: - ... open('database.sqlite') - ... except IOError: - ... raise RuntimeError from None - ... - Traceback (most recent call last): - File "<stdin>", line 4, in <module> - RuntimeError - - .. _tut-userexceptions: User-defined Exceptions @@ -321,7 +253,29 @@ User-defined Exceptions Programs may name their own exceptions by creating a new exception class (see :ref:`tut-classes` for more about Python classes). Exceptions should typically -be derived from the :exc:`Exception` class, either directly or indirectly. +be derived from the :exc:`Exception` class, either directly or indirectly. For +example:: + + >>> class MyError(Exception): + ... def __init__(self, value): + ... self.value = value + ... def __str__(self): + ... return repr(self.value) + ... + >>> try: + ... raise MyError(2*2) + ... except MyError as e: + ... print 'My exception occurred, value:', e.value + ... + My exception occurred, value: 4 + >>> raise MyError('oops!') + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + __main__.MyError: 'oops!' + +In this example, the default :meth:`__init__` of :class:`Exception` has been +overridden. The new behavior simply creates the *value* attribute. This +replaces the default behavior of creating the *args* attribute. Exception classes can be defined which do anything any other class can do, but are usually kept simple, often only offering a number of attributes that allow @@ -338,28 +292,28 @@ to create specific exception classes for different error conditions:: """Exception raised for errors in the input. Attributes: - expression -- input expression in which the error occurred - message -- explanation of the error + expr -- input expression in which the error occurred + msg -- explanation of the error """ - def __init__(self, expression, message): - self.expression = expression - self.message = message + def __init__(self, expr, msg): + self.expr = expr + self.msg = msg class TransitionError(Error): """Raised when an operation attempts a state transition that's not allowed. Attributes: - previous -- state at beginning of transition + prev -- state at beginning of transition next -- attempted new state - message -- explanation of why the specific transition is not allowed + msg -- explanation of why the specific transition is not allowed """ - def __init__(self, previous, next, message): - self.previous = previous + def __init__(self, prev, next, msg): + self.prev = prev self.next = next - self.message = message + self.msg = msg Most exceptions are defined with names that end in "Error", similar to the naming of the standard exceptions. @@ -381,48 +335,36 @@ example:: >>> try: ... raise KeyboardInterrupt ... finally: - ... print('Goodbye, world!') + ... print 'Goodbye, world!' ... Goodbye, world! Traceback (most recent call last): File "<stdin>", line 2, in <module> KeyboardInterrupt -If a :keyword:`finally` clause is present, the :keyword:`finally` clause will execute as the last task before the :keyword:`try` statement completes. The :keyword:`finally` clause runs whether or not the :keyword:`try` statement produces an exception. The following points discuss more complex cases when an exception occurs: - -* If an exception occurs during execution of the :keyword:`!try` clause, the exception may be handled by an :keyword:`except` clause. If the exception is not handled by an :keyword:`except` clause, the exception is re-raised after the :keyword:`!finally` clause has been executed. - -* An exception could occur during execution of an :keyword:`!except` or :keyword:`!else` clause. Again, the exception is re-raised after the :keyword:`!finally` clause has been executed. - -* If the :keyword:`!try` statement reaches a :keyword:`break`, :keyword:`continue` or :keyword:`return` statement, the :keyword:`finally` clause will execute just prior to the :keyword:`break`, :keyword:`continue` or :keyword:`return` statement's execution. - -* If a :keyword:`finally` clause includes a :keyword:`return` statement, the :keyword:`finally` clause's :keyword:`return` statement will execute before, and instead of, the :keyword:`return` statement in a :keyword:`try` clause. - -For example:: - - >>> def bool_return(): - ... try: - ... return True - ... finally: - ... return False - ... - >>> bool_return() - False - -A more complicated example:: +A *finally clause* is always executed before leaving the :keyword:`try` +statement, whether an exception has occurred or not. When an exception has +occurred in the :keyword:`try` clause and has not been handled by an +:keyword:`except` clause (or it has occurred in an :keyword:`except` or +:keyword:`else` clause), it is re-raised after the :keyword:`finally` clause has +been executed. The :keyword:`finally` clause is also executed "on the way out" +when any other clause of the :keyword:`try` statement is left via a +:keyword:`break`, :keyword:`continue` or :keyword:`return` statement. A more +complicated example (having :keyword:`except` and :keyword:`finally` clauses in +the same :keyword:`try` statement works as of Python 2.5):: >>> def divide(x, y): ... try: ... result = x / y ... except ZeroDivisionError: - ... print("division by zero!") + ... print "division by zero!" ... else: - ... print("result is", result) + ... print "result is", result ... finally: - ... print("executing finally clause") + ... print "executing finally clause" ... >>> divide(2, 1) - result is 2.0 + result is 2 executing finally clause >>> divide(2, 0) division by zero! @@ -436,7 +378,7 @@ A more complicated example:: As you can see, the :keyword:`finally` clause is executed in any event. The :exc:`TypeError` raised by dividing two strings is not handled by the -:keyword:`except` clause and therefore re-raised after the :keyword:`!finally` +:keyword:`except` clause and therefore re-raised after the :keyword:`finally` clause has been executed. In real world applications, the :keyword:`finally` clause is useful for @@ -455,20 +397,20 @@ succeeded or failed. Look at the following example, which tries to open a file and print its contents to the screen. :: for line in open("myfile.txt"): - print(line, end="") + print line, The problem with this code is that it leaves the file open for an indeterminate -amount of time after this part of the code has finished executing. -This is not an issue in simple scripts, but can be a problem for larger -applications. The :keyword:`with` statement allows objects like files to be -used in a way that ensures they are always cleaned up promptly and correctly. :: +amount of time after the code has finished executing. This is not an issue in +simple scripts, but can be a problem for larger applications. The +:keyword:`with` statement allows objects like files to be used in a way that +ensures they are always cleaned up promptly and correctly. :: with open("myfile.txt") as f: for line in f: - print(line, end="") + print line, After the statement is executed, the file *f* is always closed, even if a -problem was encountered while processing the lines. Objects which, like files, -provide predefined clean-up actions will indicate this in their documentation. +problem was encountered while processing the lines. Other objects which provide +predefined clean-up actions will indicate this in their documentation. diff --git a/Doc/tutorial/floatingpoint.rst b/Doc/tutorial/floatingpoint.rst index 0c0eb52..4b95570 100644 --- a/Doc/tutorial/floatingpoint.rst +++ b/Doc/tutorial/floatingpoint.rst @@ -1,7 +1,3 @@ -.. testsetup:: - - import math - .. _tut-fp-issues: ************************************************** @@ -52,18 +48,22 @@ decimal value 0.1 cannot be represented exactly as a base 2 fraction. In base 0.0001100110011001100110011001100110011001100110011... -Stop at any finite number of bits, and you get an approximation. On most -machines today, floats are approximated using a binary fraction with -the numerator using the first 53 bits starting with the most significant bit and -with the denominator as a power of two. In the case of 1/10, the binary fraction -is ``3602879701896397 / 2 ** 55`` which is close to but not exactly -equal to the true value of 1/10. +Stop at any finite number of bits, and you get an approximation. + +On a typical machine running Python, there are 53 bits of precision available +for a Python float, so the value stored internally when you enter the decimal +number ``0.1`` is the binary fraction :: + + 0.00011001100110011001100110011001100110011001100110011010 + +which is close to, but not exactly equal to, 1/10. -Many users are not aware of the approximation because of the way values are -displayed. Python only prints a decimal approximation to the true decimal -value of the binary approximation stored by the machine. On most machines, if -Python were to print the true decimal value of the binary approximation stored -for 0.1, it would have to display :: +It's easy to forget that the stored value is an approximation to the original +decimal fraction, because of the way that floats are displayed at the +interpreter prompt. Python only prints a decimal approximation to the true +decimal value of the binary approximation stored by the machine. If Python +were to print the true decimal value of the binary approximation stored for +0.1, it would have to display :: >>> 0.1 0.1000000000000000055511151231257827021181583404541015625 @@ -71,65 +71,59 @@ for 0.1, it would have to display :: That is more digits than most people find useful, so Python keeps the number of digits manageable by displaying a rounded value instead :: - >>> 1 / 10 + >>> 0.1 0.1 -Just remember, even though the printed result looks like the exact value -of 1/10, the actual stored value is the nearest representable binary fraction. - -Interestingly, there are many different decimal numbers that share the same -nearest approximate binary fraction. For example, the numbers ``0.1`` and -``0.10000000000000001`` and -``0.1000000000000000055511151231257827021181583404541015625`` are all -approximated by ``3602879701896397 / 2 ** 55``. Since all of these decimal -values share the same approximation, any one of them could be displayed -while still preserving the invariant ``eval(repr(x)) == x``. - -Historically, the Python prompt and built-in :func:`repr` function would choose -the one with 17 significant digits, ``0.10000000000000001``. Starting with -Python 3.1, Python (on most systems) is now able to choose the shortest of -these and simply display ``0.1``. - -Note that this is in the very nature of binary floating-point: this is not a bug -in Python, and it is not a bug in your code either. You'll see the same kind of -thing in all languages that support your hardware's floating-point arithmetic -(although some languages may not *display* the difference by default, or in all -output modes). +It's important to realize that this is, in a real sense, an illusion: the value +in the machine is not exactly 1/10, you're simply rounding the *display* of the +true machine value. This fact becomes apparent as soon as you try to do +arithmetic with these values :: -For more pleasant output, you may wish to use string formatting to produce a limited number of significant digits:: + >>> 0.1 + 0.2 + 0.30000000000000004 - >>> format(math.pi, '.12g') # give 12 significant digits - '3.14159265359' +Note that this is in the very nature of binary floating-point: this is not a +bug in Python, and it is not a bug in your code either. You'll see the same +kind of thing in all languages that support your hardware's floating-point +arithmetic (although some languages may not *display* the difference by +default, or in all output modes). - >>> format(math.pi, '.2f') # give 2 digits after the point - '3.14' +Other surprises follow from this one. For example, if you try to round the +value 2.675 to two decimal places, you get this :: - >>> repr(math.pi) - '3.141592653589793' + >>> round(2.675, 2) + 2.67 +The documentation for the built-in :func:`round` function says that it rounds +to the nearest value, rounding ties away from zero. Since the decimal fraction +2.675 is exactly halfway between 2.67 and 2.68, you might expect the result +here to be (a binary approximation to) 2.68. It's not, because when the +decimal string ``2.675`` is converted to a binary floating-point number, it's +again replaced with a binary approximation, whose exact value is :: -It's important to realize that this is, in a real sense, an illusion: you're -simply rounding the *display* of the true machine value. + 2.67499999999999982236431605997495353221893310546875 -One illusion may beget another. For example, since 0.1 is not exactly 1/10, -summing three values of 0.1 may not yield exactly 0.3, either:: +Since this approximation is slightly closer to 2.67 than to 2.68, it's rounded +down. - >>> .1 + .1 + .1 == .3 - False +If you're in a situation where you care which way your decimal halfway-cases +are rounded, you should consider using the :mod:`decimal` module. +Incidentally, the :mod:`decimal` module also provides a nice way to "see" the +exact value that's stored in any particular Python float :: -Also, since the 0.1 cannot get any closer to the exact value of 1/10 and -0.3 cannot get any closer to the exact value of 3/10, then pre-rounding with -:func:`round` function cannot help:: - - >>> round(.1, 1) + round(.1, 1) + round(.1, 1) == round(.3, 1) - False + >>> from decimal import Decimal + >>> Decimal(2.675) + Decimal('2.67499999999999982236431605997495353221893310546875') -Though the numbers cannot be made closer to their intended exact values, -the :func:`round` function can be useful for post-rounding so that results -with inexact values become comparable to one another:: +Another consequence is that since 0.1 is not exactly 1/10, summing ten values +of 0.1 may not yield exactly 1.0, either:: - >>> round(.1 + .1 + .1, 10) == round(.3, 10) - True + >>> sum = 0.0 + >>> for i in range(10): + ... sum += 0.1 + ... + >>> sum + 0.9999999999999999 Binary floating-point arithmetic holds many surprises like this. The problem with "0.1" is explained in precise detail below, in the "Representation Error" @@ -140,89 +134,39 @@ As that says near the end, "there are no easy answers." Still, don't be unduly wary of floating-point! The errors in Python float operations are inherited from the floating-point hardware, and on most machines are on the order of no more than 1 part in 2\*\*53 per operation. That's more than adequate for most -tasks, but you do need to keep in mind that it's not decimal arithmetic and +tasks, but you do need to keep in mind that it's not decimal arithmetic, and that every float operation can suffer a new rounding error. While pathological cases do exist, for most casual use of floating-point arithmetic you'll see the result you expect in the end if you simply round the -display of your final results to the number of decimal digits you expect. -:func:`str` usually suffices, and for finer control see the :meth:`str.format` -method's format specifiers in :ref:`formatstrings`. - -For use cases which require exact decimal representation, try using the -:mod:`decimal` module which implements decimal arithmetic suitable for -accounting applications and high-precision applications. - -Another form of exact arithmetic is supported by the :mod:`fractions` module -which implements arithmetic based on rational numbers (so the numbers like -1/3 can be represented exactly). - -If you are a heavy user of floating point operations you should take a look -at the Numerical Python package and many other packages for mathematical and -statistical operations supplied by the SciPy project. See <https://scipy.org>. - -Python provides tools that may help on those rare occasions when you really -*do* want to know the exact value of a float. The -:meth:`float.as_integer_ratio` method expresses the value of a float as a -fraction:: - - >>> x = 3.14159 - >>> x.as_integer_ratio() - (3537115888337719, 1125899906842624) - -Since the ratio is exact, it can be used to losslessly recreate the -original value:: - - >>> x == 3537115888337719 / 1125899906842624 - True +display of your final results to the number of decimal digits you expect. For +fine control over how a float is displayed see the :meth:`str.format` method's +format specifiers in :ref:`formatstrings`. -The :meth:`float.hex` method expresses a float in hexadecimal (base -16), again giving the exact value stored by your computer:: - - >>> x.hex() - '0x1.921f9f01b866ep+1' - -This precise hexadecimal representation can be used to reconstruct -the float value exactly:: - - >>> x == float.fromhex('0x1.921f9f01b866ep+1') - True - -Since the representation is exact, it is useful for reliably porting values -across different versions of Python (platform independence) and exchanging -data with other languages that support the same format (such as Java and C99). - -Another helpful tool is the :func:`math.fsum` function which helps mitigate -loss-of-precision during summation. It tracks "lost digits" as values are -added onto a running total. That can make a difference in overall accuracy -so that the errors do not accumulate to the point where they affect the -final total: - - >>> sum([0.1] * 10) == 1.0 - False - >>> math.fsum([0.1] * 10) == 1.0 - True .. _tut-fp-error: Representation Error ==================== -This section explains the "0.1" example in detail, and shows how you can perform -an exact analysis of cases like this yourself. Basic familiarity with binary -floating-point representation is assumed. +This section explains the "0.1" example in detail, and shows how you can +perform an exact analysis of cases like this yourself. Basic familiarity with +binary floating-point representation is assumed. :dfn:`Representation error` refers to the fact that some (most, actually) decimal fractions cannot be represented exactly as binary (base 2) fractions. This is the chief reason why Python (or Perl, C, C++, Java, Fortran, and many -others) often won't display the exact decimal number you expect. +others) often won't display the exact decimal number you expect:: + + >>> 0.1 + 0.2 + 0.30000000000000004 -Why is that? 1/10 is not exactly representable as a binary fraction. Almost all -machines today (November 2000) use IEEE-754 floating point arithmetic, and -almost all platforms map Python floats to IEEE-754 "double precision". 754 -doubles contain 53 bits of precision, so on input the computer strives to -convert 0.1 to the closest fraction it can of the form *J*/2**\ *N* where *J* is -an integer containing exactly 53 bits. Rewriting :: +Why is that? 1/10 and 2/10 are not exactly representable as a binary +fraction. Almost all machines today (July 2010) use IEEE-754 floating point +arithmetic, and almost all platforms map Python floats to IEEE-754 "double +precision". 754 doubles contain 53 bits of precision, so on input the computer +strives to convert 0.1 to the closest fraction it can of the form *J*/2**\ *N* +where *J* is an integer containing exactly 53 bits. Rewriting :: 1 / 10 ~= J / (2**N) @@ -233,11 +177,15 @@ as :: and recalling that *J* has exactly 53 bits (is ``>= 2**52`` but ``< 2**53``), the best value for *N* is 56:: - >>> 2**52 <= 2**56 // 10 < 2**53 - True + >>> 2**52 + 4503599627370496 + >>> 2**53 + 9007199254740992 + >>> 2**56/10 + 7205759403792793 -That is, 56 is the only value for *N* that leaves *J* with exactly 53 bits. The -best possible value for *J* is then that quotient rounded:: +That is, 56 is the only value for *N* that leaves *J* with exactly 53 bits. +The best possible value for *J* is then that quotient rounded:: >>> q, r = divmod(2**56, 10) >>> r @@ -249,52 +197,30 @@ by rounding up:: >>> q+1 7205759403792794 -Therefore the best possible approximation to 1/10 in 754 double precision is:: - - 7205759403792794 / 2 ** 56 - -Dividing both the numerator and denominator by two reduces the fraction to:: +Therefore the best possible approximation to 1/10 in 754 double precision is +that over 2\*\*56, or :: - 3602879701896397 / 2 ** 55 + 7205759403792794 / 72057594037927936 Note that since we rounded up, this is actually a little bit larger than 1/10; -if we had not rounded up, the quotient would have been a little bit smaller than -1/10. But in no case can it be *exactly* 1/10! +if we had not rounded up, the quotient would have been a little bit smaller +than 1/10. But in no case can it be *exactly* 1/10! So the computer never "sees" 1/10: what it sees is the exact fraction given above, the best 754 double approximation it can get:: - >>> 0.1 * 2 ** 55 - 3602879701896397.0 - -If we multiply that fraction by 10\*\*55, we can see the value out to -55 decimal digits:: - - >>> 3602879701896397 * 10 ** 55 // 2 ** 55 - 1000000000000000055511151231257827021181583404541015625 - -meaning that the exact number stored in the computer is equal to -the decimal value 0.1000000000000000055511151231257827021181583404541015625. -Instead of displaying the full decimal value, many languages (including -older versions of Python), round the result to 17 significant digits:: - - >>> format(0.1, '.17f') - '0.10000000000000001' - -The :mod:`fractions` and :mod:`decimal` modules make these calculations -easy:: - - >>> from decimal import Decimal - >>> from fractions import Fraction - - >>> Fraction.from_float(0.1) - Fraction(3602879701896397, 36028797018963968) + >>> .1 * 2**56 + 7205759403792794.0 - >>> (0.1).as_integer_ratio() - (3602879701896397, 36028797018963968) +If we multiply that fraction by 10\*\*30, we can see the (truncated) value of +its 30 most significant decimal digits:: - >>> Decimal.from_float(0.1) - Decimal('0.1000000000000000055511151231257827021181583404541015625') + >>> 7205759403792794 * 10**30 // 2**56 + 100000000000000005551115123125L - >>> format(Decimal.from_float(0.1), '.17') - '0.10000000000000001' +meaning that the exact number stored in the computer is approximately equal to +the decimal value 0.100000000000000005551115123125. In versions prior to +Python 2.7 and Python 3.1, Python rounded this value to 17 significant digits, +giving '0.10000000000000001'. In current versions, Python displays a value +based on the shortest decimal fraction that rounds correctly back to the true +binary value, resulting simply in '0.1'. diff --git a/Doc/tutorial/index.rst b/Doc/tutorial/index.rst index 8ee011e..c14b1d6 100644 --- a/Doc/tutorial/index.rst +++ b/Doc/tutorial/index.rst @@ -53,7 +53,6 @@ The :ref:`glossary` is also worth going through. classes.rst stdlib.rst stdlib2.rst - venv.rst whatnow.rst interactive.rst floatingpoint.rst diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst index a404f4b..78d6ba3 100644 --- a/Doc/tutorial/inputoutput.rst +++ b/Doc/tutorial/inputoutput.rst @@ -15,46 +15,24 @@ Fancier Output Formatting ========================= So far we've encountered two ways of writing values: *expression statements* and -the :func:`print` function. (A third way is using the :meth:`write` method +the :keyword:`print` statement. (A third way is using the :meth:`write` method of file objects; the standard output file can be referenced as ``sys.stdout``. See the Library Reference for more information on this.) Often you'll want more control over the formatting of your output than simply -printing space-separated values. There are several ways to format output. +printing space-separated values. There are two ways to format your output; the +first way is to do all the string handling yourself; using string slicing and +concatenation operations you can create any layout you can imagine. The +string types have some methods that perform useful operations for padding +strings to a given column width; these will be discussed shortly. The second +way is to use the :meth:`str.format` method. -* To use :ref:`formatted string literals <tut-f-strings>`, begin a string - with ``f`` or ``F`` before the opening quotation mark or triple quotation mark. - Inside this string, you can write a Python expression between ``{`` and ``}`` - characters that can refer to variables or literal values. +The :mod:`string` module contains a :class:`~string.Template` class which offers +yet another way to substitute values into strings. - :: - - >>> year = 2016 - >>> event = 'Referendum' - >>> f'Results of the {year} {event}' - 'Results of the 2016 Referendum' - -* The :meth:`str.format` method of strings requires more manual - effort. You'll still use ``{`` and ``}`` to mark where a variable - will be substituted and can provide detailed formatting directives, - but you'll also need to provide the information to be formatted. - - :: - - >>> yes_votes = 42_572_654 - >>> no_votes = 43_132_495 - >>> percentage = yes_votes / (yes_votes + no_votes) - >>> '{:-9} YES votes {:2.2%}'.format(yes_votes, percentage) - ' 42572654 YES votes 49.67%' - -* Finally, you can do all the string handling yourself by using string slicing and - concatenation operations to create any layout you can imagine. The - string type has some methods that perform useful operations for padding - strings to a given column width. - -When you don't need fancy output but just want a quick display of some -variables for debugging purposes, you can convert any value to a string with -the :func:`repr` or :func:`str` functions. +One question remains, of course: how do you convert values to strings? Luckily, +Python has ways to convert any value to a string: pass it to the :func:`repr` +or :func:`str` functions. The :func:`str` function is meant to return representations of values which are fairly human-readable, while :func:`repr` is meant to generate representations @@ -62,8 +40,8 @@ which can be read by the interpreter (or will force a :exc:`SyntaxError` if there is no equivalent syntax). For objects which don't have a particular representation for human consumption, :func:`str` will return the same value as :func:`repr`. Many values, such as numbers or structures like lists and -dictionaries, have the same representation using either function. Strings, in -particular, have two distinct representations. +dictionaries, have the same representation using either function. Strings and +floating point numbers, in particular, have two distinct representations. Some examples:: @@ -72,188 +50,159 @@ Some examples:: 'Hello, world.' >>> repr(s) "'Hello, world.'" - >>> str(1/7) + >>> str(1.0/7.0) + '0.142857142857' + >>> repr(1.0/7.0) '0.14285714285714285' >>> x = 10 * 3.25 >>> y = 200 * 200 >>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...' - >>> print(s) + >>> print s The value of x is 32.5, and y is 40000... >>> # The repr() of a string adds string quotes and backslashes: ... hello = 'hello, world\n' >>> hellos = repr(hello) - >>> print(hellos) + >>> print hellos 'hello, world\n' >>> # The argument to repr() may be any Python object: ... repr((x, y, ('spam', 'eggs'))) "(32.5, 40000, ('spam', 'eggs'))" -The :mod:`string` module contains a :class:`~string.Template` class that offers -yet another way to substitute values into strings, using placeholders like -``$x`` and replacing them with values from a dictionary, but offers much less -control of the formatting. - - -.. _tut-f-strings: - -Formatted String Literals -------------------------- +Here are two ways to write a table of squares and cubes:: -:ref:`Formatted string literals <f-strings>` (also called f-strings for -short) let you include the value of Python expressions inside a string by -prefixing the string with ``f`` or ``F`` and writing expressions as -``{expression}``. - -An optional format specifier can follow the expression. This allows greater -control over how the value is formatted. The following example rounds pi to -three places after the decimal:: - - >>> import math - >>> print(f'The value of pi is approximately {math.pi:.3f}.') - The value of pi is approximately 3.142. - -Passing an integer after the ``':'`` will cause that field to be a minimum -number of characters wide. This is useful for making columns line up. :: - - >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678} - >>> for name, phone in table.items(): - ... print(f'{name:10} ==> {phone:10d}') + >>> for x in range(1, 11): + ... print repr(x).rjust(2), repr(x*x).rjust(3), + ... # Note trailing comma on previous line + ... print repr(x*x*x).rjust(4) ... - Sjoerd ==> 4127 - Jack ==> 4098 - Dcab ==> 7678 + 1 1 1 + 2 4 8 + 3 9 27 + 4 16 64 + 5 25 125 + 6 36 216 + 7 49 343 + 8 64 512 + 9 81 729 + 10 100 1000 -Other modifiers can be used to convert the value before it is formatted. -``'!a'`` applies :func:`ascii`, ``'!s'`` applies :func:`str`, and ``'!r'`` -applies :func:`repr`:: + >>> for x in range(1,11): + ... print '{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x) + ... + 1 1 1 + 2 4 8 + 3 9 27 + 4 16 64 + 5 25 125 + 6 36 216 + 7 49 343 + 8 64 512 + 9 81 729 + 10 100 1000 - >>> animals = 'eels' - >>> print(f'My hovercraft is full of {animals}.') - My hovercraft is full of eels. - >>> print(f'My hovercraft is full of {animals!r}.') - My hovercraft is full of 'eels'. +(Note that in the first example, one space between each column was added by the +way :keyword:`print` works: by default it adds spaces between its arguments.) -For a reference on these format specifications, see -the reference guide for the :ref:`formatspec`. +This example demonstrates the :meth:`str.rjust` method of string +objects, which right-justifies a string in a field of a given width by padding +it with spaces on the left. There are similar methods :meth:`str.ljust` and +:meth:`str.center`. These methods do not write anything, they just return a +new string. If the input string is too long, they don't truncate it, but +return it unchanged; this will mess up your column lay-out but that's usually +better than the alternative, which would be lying about a value. (If you +really want truncation you can always add a slice operation, as in +``x.ljust(n)[:n]``.) -.. _tut-string-format: +There is another method, :meth:`str.zfill`, which pads a numeric string on the +left with zeros. It understands about plus and minus signs:: -The String format() Method --------------------------- + >>> '12'.zfill(5) + '00012' + >>> '-3.14'.zfill(7) + '-003.14' + >>> '3.14159265359'.zfill(5) + '3.14159265359' Basic usage of the :meth:`str.format` method looks like this:: - >>> print('We are the {} who say "{}!"'.format('knights', 'Ni')) + >>> print 'We are the {} who say "{}!"'.format('knights', 'Ni') We are the knights who say "Ni!" The brackets and characters within them (called format fields) are replaced with the objects passed into the :meth:`str.format` method. A number in the -brackets can be used to refer to the position of the object passed into the +brackets refers to the position of the object passed into the :meth:`str.format` method. :: - >>> print('{0} and {1}'.format('spam', 'eggs')) + >>> print '{0} and {1}'.format('spam', 'eggs') spam and eggs - >>> print('{1} and {0}'.format('spam', 'eggs')) + >>> print '{1} and {0}'.format('spam', 'eggs') eggs and spam If keyword arguments are used in the :meth:`str.format` method, their values are referred to by using the name of the argument. :: - >>> print('This {food} is {adjective}.'.format( - ... food='spam', adjective='absolutely horrible')) + >>> print 'This {food} is {adjective}.'.format( + ... food='spam', adjective='absolutely horrible') This spam is absolutely horrible. Positional and keyword arguments can be arbitrarily combined:: - >>> print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred', - other='Georg')) + >>> print 'The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred', + ... other='Georg') The story of Bill, Manfred, and Georg. +``'!s'`` (apply :func:`str`) and ``'!r'`` (apply :func:`repr`) can be used to +convert the value before it is formatted. :: + + >>> import math + >>> print 'The value of PI is approximately {}.'.format(math.pi) + The value of PI is approximately 3.14159265359. + >>> print 'The value of PI is approximately {!r}.'.format(math.pi) + The value of PI is approximately 3.141592653589793. + +An optional ``':'`` and format specifier can follow the field name. This allows +greater control over how the value is formatted. The following example +rounds Pi to three places after the decimal. + + >>> import math + >>> print 'The value of PI is approximately {0:.3f}.'.format(math.pi) + The value of PI is approximately 3.142. + +Passing an integer after the ``':'`` will cause that field to be a minimum +number of characters wide. This is useful for making tables pretty. :: + + >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678} + >>> for name, phone in table.items(): + ... print '{0:10} ==> {1:10d}'.format(name, phone) + ... + Jack ==> 4098 + Dcab ==> 7678 + Sjoerd ==> 4127 + If you have a really long format string that you don't want to split up, it would be nice if you could reference the variables to be formatted by name instead of by position. This can be done by simply passing the dict and using square brackets ``'[]'`` to access the keys :: >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} - >>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; ' - ... 'Dcab: {0[Dcab]:d}'.format(table)) + >>> print ('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; ' + ... 'Dcab: {0[Dcab]:d}'.format(table)) Jack: 4098; Sjoerd: 4127; Dcab: 8637678 This could also be done by passing the table as keyword arguments with the '**' notation. :: >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} - >>> print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table)) + >>> print 'Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table) Jack: 4098; Sjoerd: 4127; Dcab: 8637678 This is particularly useful in combination with the built-in function :func:`vars`, which returns a dictionary containing all local variables. -As an example, the following lines produce a tidily-aligned -set of columns giving integers and their squares and cubes:: - - >>> for x in range(1, 11): - ... print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x)) - ... - 1 1 1 - 2 4 8 - 3 9 27 - 4 16 64 - 5 25 125 - 6 36 216 - 7 49 343 - 8 64 512 - 9 81 729 - 10 100 1000 - For a complete overview of string formatting with :meth:`str.format`, see :ref:`formatstrings`. -Manual String Formatting ------------------------- - -Here's the same table of squares and cubes, formatted manually:: - - >>> for x in range(1, 11): - ... print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ') - ... # Note use of 'end' on previous line - ... print(repr(x*x*x).rjust(4)) - ... - 1 1 1 - 2 4 8 - 3 9 27 - 4 16 64 - 5 25 125 - 6 36 216 - 7 49 343 - 8 64 512 - 9 81 729 - 10 100 1000 - -(Note that the one space between each column was added by the -way :func:`print` works: it always adds spaces between its arguments.) - -The :meth:`str.rjust` method of string objects right-justifies a string in a -field of a given width by padding it with spaces on the left. There are -similar methods :meth:`str.ljust` and :meth:`str.center`. These methods do -not write anything, they just return a new string. If the input string is too -long, they don't truncate it, but return it unchanged; this will mess up your -column lay-out but that's usually better than the alternative, which would be -lying about a value. (If you really want truncation you can always add a -slice operation, as in ``x.ljust(n)[:n]``.) - -There is another method, :meth:`str.zfill`, which pads a numeric string on the -left with zeros. It understands about plus and minus signs:: - - >>> '12'.zfill(5) - '00012' - >>> '-3.14'.zfill(7) - '-003.14' - >>> '3.14159265359'.zfill(5) - '3.14159265359' - - Old string formatting --------------------- @@ -263,10 +212,10 @@ to the right argument, and returns the string resulting from this formatting operation. For example:: >>> import math - >>> print('The value of pi is approximately %5.3f.' % math.pi) - The value of pi is approximately 3.142. + >>> print 'The value of PI is approximately %5.3f.' % math.pi + The value of PI is approximately 3.142. -More information can be found in the :ref:`old-string-formatting` section. +More information can be found in the :ref:`string-formatting` section. .. _tut-files: @@ -278,16 +227,13 @@ Reading and Writing Files builtin: open object: file -:func:`open` returns a :term:`file object`, and is most commonly used with -two arguments: ``open(filename, mode)``. +:func:`open` returns a file object, and is most commonly used with two +arguments: ``open(filename, mode)``. :: >>> f = open('workfile', 'w') - -.. XXX str(f) is <io.TextIOWrapper object at 0x82e8dc4> - - >>> print(f) + >>> print f <open file 'workfile', mode 'w' at 80a0960> The first argument is a string containing the filename. The second argument is @@ -299,51 +245,15 @@ automatically added to the end. ``'r+'`` opens the file for both reading and writing. The *mode* argument is optional; ``'r'`` will be assumed if it's omitted. -Normally, files are opened in :dfn:`text mode`, that means, you read and write -strings from and to the file, which are encoded in a specific encoding. If -encoding is not specified, the default is platform dependent (see -:func:`open`). ``'b'`` appended to the mode opens the file in -:dfn:`binary mode`: now the data is read and written in the form of bytes -objects. This mode should be used for all files that don't contain text. - -In text mode, the default when reading is to convert platform-specific line -endings (``\n`` on Unix, ``\r\n`` on Windows) to just ``\n``. When writing in -text mode, the default is to convert occurrences of ``\n`` back to -platform-specific line endings. This behind-the-scenes modification -to file data is fine for text files, but will corrupt binary data like that in -:file:`JPEG` or :file:`EXE` files. Be very careful to use binary mode when -reading and writing such files. - -It is good practice to use the :keyword:`with` keyword when dealing -with file objects. The advantage is that the file is properly closed -after its suite finishes, even if an exception is raised at some -point. Using :keyword:`!with` is also much shorter than writing -equivalent :keyword:`try`\ -\ :keyword:`finally` blocks:: - - >>> with open('workfile') as f: - ... read_data = f.read() - - >>> # We can check that the file has been automatically closed. - >>> f.closed - True - -If you're not using the :keyword:`with` keyword, then you should call -``f.close()`` to close the file and immediately free up any system -resources used by it. If you don't explicitly close a file, Python's -garbage collector will eventually destroy the object and close the -open file for you, but the file may stay open for a while. Another -risk is that different Python implementations will do this clean-up at -different times. - -After a file object is closed, either by a :keyword:`with` statement -or by calling ``f.close()``, attempts to use the file object will -automatically fail. :: - - >>> f.close() - >>> f.read() - Traceback (most recent call last): - File "<stdin>", line 1, in <module> - ValueError: I/O operation on closed file. +On Windows, ``'b'`` appended to the mode opens the file in binary mode, so there +are also modes like ``'rb'``, ``'wb'``, and ``'r+b'``. Python on Windows makes +a distinction between text and binary files; the end-of-line characters in text +files are automatically altered slightly when data is read or written. This +behind-the-scenes modification to file data is fine for ASCII text files, but +it'll corrupt binary data like that in :file:`JPEG` or :file:`EXE` files. Be +very careful to use binary mode when reading and writing such files. On Unix, +it doesn't hurt to append a ``'b'`` to the mode, so you can use it +platform-independently for all binary files. .. _tut-filemethods: @@ -355,13 +265,12 @@ The rest of the examples in this section will assume that a file object called ``f`` has already been created. To read a file's contents, call ``f.read(size)``, which reads some quantity of -data and returns it as a string (in text mode) or bytes object (in binary mode). -*size* is an optional numeric argument. When *size* is omitted or negative, the -entire contents of the file will be read and returned; it's your problem if the -file is twice as large as your machine's memory. Otherwise, at most *size* -characters (in text mode) or *size* bytes (in binary mode) are read and returned. -If the end of the file has been reached, ``f.read()`` will return an empty -string (``''``). :: +data and returns it as a string. *size* is an optional numeric argument. When +*size* is omitted or negative, the entire contents of the file will be read and +returned; it's your problem if the file is twice as large as your machine's +memory. Otherwise, at most *size* bytes are read and returned. If the end of +the file has been reached, ``f.read()`` will return an empty string (``""``). +:: >>> f.read() 'This is the entire file.\n' @@ -373,7 +282,7 @@ is left at the end of the string, and is only omitted on the last line of the file if the file doesn't end in a newline. This makes the return value unambiguous; if ``f.readline()`` returns an empty string, the end of the file has been reached, while a blank line is represented by ``'\n'``, a string -containing only a single newline. :: +containing only a single newline. :: >>> f.readline() 'This is the first line of the file.\n' @@ -386,8 +295,8 @@ For reading lines from a file, you can loop over the file object. This is memory efficient, fast, and leads to simple code:: >>> for line in f: - ... print(line, end='') - ... + print line, + This is the first line of the file. Second line of the file @@ -395,47 +304,54 @@ If you want to read all the lines of a file in a list you can also use ``list(f)`` or ``f.readlines()``. ``f.write(string)`` writes the contents of *string* to the file, returning -the number of characters written. :: +``None``. :: >>> f.write('This is a test\n') - 15 -Other types of objects need to be converted -- either to a string (in text mode) -or a bytes object (in binary mode) -- before writing them:: +To write something other than a string, it needs to be converted to a string +first:: >>> value = ('the answer', 42) - >>> s = str(value) # convert the tuple to string + >>> s = str(value) >>> f.write(s) - 18 -``f.tell()`` returns an integer giving the file object's current position in the file -represented as number of bytes from the beginning of the file when in binary mode and -an opaque number when in text mode. - -To change the file object's position, use ``f.seek(offset, whence)``. The position is computed +``f.tell()`` returns an integer giving the file object's current position in the +file, measured in bytes from the beginning of the file. To change the file +object's position, use ``f.seek(offset, from_what)``. The position is computed from adding *offset* to a reference point; the reference point is selected by -the *whence* argument. A *whence* value of 0 measures from the beginning +the *from_what* argument. A *from_what* value of 0 measures from the beginning of the file, 1 uses the current file position, and 2 uses the end of the file as -the reference point. *whence* can be omitted and defaults to 0, using the +the reference point. *from_what* can be omitted and defaults to 0, using the beginning of the file as the reference point. :: - >>> f = open('workfile', 'rb+') - >>> f.write(b'0123456789abcdef') - 16 + >>> f = open('workfile', 'r+') + >>> f.write('0123456789abcdef') >>> f.seek(5) # Go to the 6th byte in the file - 5 >>> f.read(1) - b'5' + '5' >>> f.seek(-3, 2) # Go to the 3rd byte before the end - 13 >>> f.read(1) - b'd' + 'd' + +When you're done with a file, call ``f.close()`` to close it and free up any +system resources taken up by the open file. After calling ``f.close()``, +attempts to use the file object will automatically fail. :: + + >>> f.close() + >>> f.read() + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + ValueError: I/O operation on closed file + +It is good practice to use the :keyword:`with` keyword when dealing with file +objects. This has the advantage that the file is properly closed after its +suite finishes, even if an exception is raised on the way. It is also much +shorter than writing equivalent :keyword:`try`\ -\ :keyword:`finally` blocks:: -In text files (those opened without a ``b`` in the mode string), only seeks -relative to the beginning of the file are allowed (the exception being seeking -to the very file end with ``seek(0, 2)``) and the only valid *offset* values are -those returned from the ``f.tell()``, or zero. Any other *offset* value produces -undefined behaviour. + >>> with open('workfile', 'r') as f: + ... read_data = f.read() + >>> f.closed + True File objects have some additional methods, such as :meth:`~file.isatty` and :meth:`~file.truncate` which are less frequently used; consult the Library @@ -479,12 +395,12 @@ simple line of code:: '[1, "simple", "list"]' Another variant of the :func:`~json.dumps` function, called :func:`~json.dump`, -simply serializes the object to a :term:`text file`. So if ``f`` is a -:term:`text file` object opened for writing, we can do this:: +simply serializes the object to a file. So if ``f`` is a :term:`file object` +opened for writing, we can do this:: json.dump(x, f) -To decode the object again, if ``f`` is a :term:`text file` object which has +To decode the object again, if ``f`` is a :term:`file object` which has been opened for reading:: x = json.load(f) @@ -503,3 +419,4 @@ The reference for the :mod:`json` module contains an explanation of this. written in other languages. It is also insecure by default: deserializing pickle data coming from an untrusted source can execute arbitrary code, if the data was crafted by a skilled attacker. + diff --git a/Doc/tutorial/interactive.rst b/Doc/tutorial/interactive.rst index c0eb1fe..d109018 100644 --- a/Doc/tutorial/interactive.rst +++ b/Doc/tutorial/interactive.rst @@ -7,27 +7,140 @@ Interactive Input Editing and History Substitution Some versions of the Python interpreter support editing of the current input line and history substitution, similar to facilities found in the Korn shell and the GNU Bash shell. This is implemented using the `GNU Readline`_ library, -which supports various styles of editing. This library has its own -documentation which we won't duplicate here. +which supports Emacs-style and vi-style editing. This library has its own +documentation which I won't duplicate here; however, the basics are easily +explained. The interactive editing and history described here are optionally +available in the Unix and Cygwin versions of the interpreter. + +This chapter does *not* document the editing facilities of Mark Hammond's +PythonWin package or the Tk-based environment, IDLE, distributed with Python. +The command line history recall which operates within DOS boxes on NT and some +other DOS and Windows flavors is yet another beast. + + +.. _tut-lineediting: + +Line Editing +============ + +If supported, input line editing is active whenever the interpreter prints a +primary or secondary prompt. The current line can be edited using the +conventional Emacs control characters. The most important of these are: +:kbd:`C-A` (Control-A) moves the cursor to the beginning of the line, :kbd:`C-E` +to the end, :kbd:`C-B` moves it one position to the left, :kbd:`C-F` to the +right. Backspace erases the character to the left of the cursor, :kbd:`C-D` the +character to its right. :kbd:`C-K` kills (erases) the rest of the line to the +right of the cursor, :kbd:`C-Y` yanks back the last killed string. +:kbd:`C-underscore` undoes the last change you made; it can be repeated for +cumulative effect. + + +.. _tut-history: + +History Substitution +==================== + +History substitution works as follows. All non-empty input lines issued are +saved in a history buffer, and when a new prompt is given you are positioned on +a new line at the bottom of this buffer. :kbd:`C-P` moves one line up (back) in +the history buffer, :kbd:`C-N` moves one down. Any line in the history buffer +can be edited; an asterisk appears in front of the prompt to mark a line as +modified. Pressing the :kbd:`Return` key passes the current line to the +interpreter. :kbd:`C-R` starts an incremental reverse search; :kbd:`C-S` starts +a forward search. .. _tut-keybindings: -Tab Completion and History Editing -================================== +Key Bindings +============ + +The key bindings and some other parameters of the Readline library can be +customized by placing commands in an initialization file called +:file:`~/.inputrc`. Key bindings have the form :: + + key-name: function-name + +or :: + + "string": function-name + +and options can be set with :: + + set option-name value + +For example:: + + # I prefer vi-style editing: + set editing-mode vi + + # Edit using a single line: + set horizontal-scroll-mode On -Completion of variable and module names is -:ref:`automatically enabled <rlcompleter-config>` at interpreter startup so -that the :kbd:`Tab` key invokes the completion function; it looks at -Python statement names, the current local variables, and the available -module names. For dotted expressions such as ``string.a``, it will evaluate -the expression up to the final ``'.'`` and then suggest completions from -the attributes of the resulting object. Note that this may execute -application-defined code if an object with a :meth:`__getattr__` method -is part of the expression. The default configuration also saves your -history into a file named :file:`.python_history` in your user directory. -The history will be available again during the next interactive interpreter -session. + # Rebind some keys: + Meta-h: backward-kill-word + "\C-u": universal-argument + "\C-x\C-r": re-read-init-file + +Note that the default binding for :kbd:`Tab` in Python is to insert a :kbd:`Tab` +character instead of Readline's default filename completion function. If you +insist, you can override this by putting :: + + Tab: complete + +in your :file:`~/.inputrc`. (Of course, this makes it harder to type indented +continuation lines if you're accustomed to using :kbd:`Tab` for that purpose.) + +.. index:: + module: rlcompleter + module: readline + +Automatic completion of variable and module names is optionally available. To +enable it in the interpreter's interactive mode, add the following to your +startup file: [#]_ :: + + import rlcompleter, readline + readline.parse_and_bind('tab: complete') + +This binds the :kbd:`Tab` key to the completion function, so hitting the +:kbd:`Tab` key twice suggests completions; it looks at Python statement names, +the current local variables, and the available module names. For dotted +expressions such as ``string.a``, it will evaluate the expression up to the +final ``'.'`` and then suggest completions from the attributes of the resulting +object. Note that this may execute application-defined code if an object with a +:meth:`__getattr__` method is part of the expression. + +A more capable startup file might look like this example. Note that this +deletes the names it creates once they are no longer needed; this is done since +the startup file is executed in the same namespace as the interactive commands, +and removing the names avoids creating side effects in the interactive +environment. You may find it convenient to keep some of the imported modules, +such as :mod:`os`, which turn out to be needed in most sessions with the +interpreter. :: + + # Add auto-completion and a stored history file of commands to your Python + # interactive interpreter. Requires Python 2.0+, readline. Autocomplete is + # bound to the Esc key by default (you can change it - see readline docs). + # + # Store the file in ~/.pystartup, and set an environment variable to point + # to it: "export PYTHONSTARTUP=~/.pystartup" in bash. + + import atexit + import os + import readline + import rlcompleter + + historyPath = os.path.expanduser("~/.pyhistory") + + def save_history(historyPath=historyPath): + import readline + readline.write_history_file(historyPath) + + if os.path.exists(historyPath): + readline.read_history_file(historyPath) + + atexit.register(save_history) + del os, atexit, readline, rlcompleter, save_history, historyPath .. _tut-commentary: @@ -49,6 +162,14 @@ into other applications. Another similar enhanced interactive environment is bpython_. +.. rubric:: Footnotes + +.. [#] Python will execute the contents of a file identified by the + :envvar:`PYTHONSTARTUP` environment variable when you start an interactive + interpreter. To customize Python even for non-interactive mode, see + :ref:`tut-customize`. + + .. _GNU Readline: https://tiswww.case.edu/php/chet/readline/rltop.html -.. _IPython: https://ipython.org/ -.. _bpython: https://www.bpython-interpreter.org/ +.. _IPython: http://ipython.scipy.org/ +.. _bpython: http://www.bpython-interpreter.org/ diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index b78d296..b727be0 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -10,38 +10,38 @@ Using the Python Interpreter Invoking the Interpreter ======================== -The Python interpreter is usually installed as :file:`/usr/local/bin/python3.9` -on those machines where it is available; putting :file:`/usr/local/bin` in your -Unix shell's search path makes it possible to start it by typing the command: +The Python interpreter is usually installed as :file:`/usr/local/bin/python` on +those machines where it is available; putting :file:`/usr/local/bin` in your +Unix shell's search path makes it possible to start it by typing the command :: -.. code-block:: text + python - python3.9 +to the shell. Since the choice of the directory where the interpreter lives is +an installation option, other places are possible; check with your local Python +guru or system administrator. (E.g., :file:`/usr/local/python` is a popular +alternative location.) -to the shell. [#]_ Since the choice of the directory where the interpreter lives -is an installation option, other places are possible; check with your local -Python guru or system administrator. (E.g., :file:`/usr/local/python` is a -popular alternative location.) +On Windows machines, the Python installation is usually placed in +:file:`C:\\Python27`, though you can change this when you're running the +installer. To add this directory to your path, you can type the following +command into the command prompt in a DOS box:: -On Windows machines where you have installed Python from the :ref:`Microsoft Store -<windows-store>`, the :file:`python3.9` command will be available. If you have -the :ref:`py.exe launcher <launcher>` installed, you can use the :file:`py` -command. See :ref:`setting-envvars` for other ways to launch Python. + set path=%path%;C:\python27 Typing an end-of-file character (:kbd:`Control-D` on Unix, :kbd:`Control-Z` on Windows) at the primary prompt causes the interpreter to exit with a zero exit status. If that doesn't work, you can exit the interpreter by typing the following command: ``quit()``. -The interpreter's line-editing features include interactive editing, history -substitution and code completion on systems that support the `GNU Readline -<https://tiswww.case.edu/php/chet/readline/rltop.html>`_ library. -Perhaps the quickest check to see whether command line editing is supported is -typing :kbd:`Control-P` to the first Python prompt you get. If it beeps, you -have command line editing; see Appendix :ref:`tut-interacting` for an -introduction to the keys. If nothing appears to happen, or if ``^P`` is -echoed, command line editing isn't available; you'll only be able to use -backspace to remove characters from the current line. +The interpreter's line-editing features usually aren't very sophisticated. On +Unix, whoever installed the interpreter may have enabled support for the GNU +readline library, which adds more elaborate interactive editing and history +features. Perhaps the quickest check to see whether command line editing is +supported is typing :kbd:`Control-P` to the first Python prompt you get. If it beeps, +you have command line editing; see Appendix :ref:`tut-interacting` for an +introduction to the keys. If nothing appears to happen, or if ``^P`` is echoed, +command line editing isn't available; you'll only be able to use backspace to +remove characters from the current line. The interpreter operates somewhat like the Unix shell: when called with standard input connected to a tty device, it reads and executes commands interactively; @@ -62,7 +62,7 @@ When a script file is used, it is sometimes useful to be able to run the script and enter interactive mode afterwards. This can be done by passing :option:`-i` before the script. -All command line options are described in :ref:`using-on-general`. +All command-line options are described in :ref:`using-on-general`. .. _tut-argpassing: @@ -97,20 +97,17 @@ before printing the first prompt: .. code-block:: shell-session - $ python3.9 - Python 3.9 (default, June 4 2019, 09:25:04) - [GCC 4.8.2] on linux + python + Python 2.7 (#1, Feb 28 2010, 00:02:06) Type "help", "copyright", "credits" or "license" for more information. >>> -.. XXX update for new releases - Continuation lines are needed when entering a multi-line construct. As an example, take a look at this :keyword:`if` statement:: - >>> the_world_is_flat = True + >>> the_world_is_flat = 1 >>> if the_world_is_flat: - ... print("Be careful not to fall off!") + ... print "Be careful not to fall off!" ... Be careful not to fall off! @@ -129,14 +126,7 @@ The Interpreter and Its Environment Source Code Encoding -------------------- -By default, Python source files are treated as encoded in UTF-8. In that -encoding, characters of most languages in the world can be used simultaneously -in string literals, identifiers and comments --- although the standard library -only uses ASCII characters for identifiers, a convention that any portable code -should follow. To display all these characters properly, your editor must -recognize that the file is UTF-8, and it must use a font that supports all the -characters in the file. - +By default, Python source files are treated as encoded in ASCII. To declare an encoding other than the default one, a special comment line should be added as the *first* line of the file. The syntax is as follows:: @@ -153,11 +143,6 @@ One exception to the *first line* rule is when the source code starts with a :ref:`UNIX "shebang" line <tut-scripts>`. In this case, the encoding declaration should be added as the second line of the file. For example:: - #!/usr/bin/env python3 + #!/usr/bin/env python # -*- coding: cp1252 -*- -.. rubric:: Footnotes - -.. [#] On Unix, the Python 3.x interpreter is by default not installed with the - executable named ``python``, so that it does not conflict with a - simultaneously installed Python 2.x executable. diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst index 2a16661..2ff776e 100644 --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -11,8 +11,6 @@ with a prompt are output from the interpreter. Note that a secondary prompt on a line by itself in an example means you must type a blank line; this is used to end a multi-line command. -.. index:: single: # (hash); comment - Many of the examples in this manual, even those entered at the interactive prompt, include comments. Comments in Python start with the hash character, ``#``, and extend to the end of the physical line. A comment may appear at the @@ -53,24 +51,28 @@ For example:: 4 >>> 50 - 5*6 20 - >>> (50 - 5*6) / 4 + >>> (50 - 5.0*6) / 4 5.0 - >>> 8 / 5 # division always returns a floating point number + >>> 8 / 5.0 1.6 The integer numbers (e.g. ``2``, ``4``, ``20``) have type :class:`int`, the ones with a fractional part (e.g. ``5.0``, ``1.6``) have type :class:`float`. We will see more about numeric types later in the tutorial. -Division (``/``) always returns a float. To do :term:`floor division` and -get an integer result (discarding any fractional result) you can use the ``//`` -operator; to calculate the remainder you can use ``%``:: +The return type of a division (``/``) operation depends on its operands. If +both operands are of type :class:`int`, :term:`floor division` is performed +and an :class:`int` is returned. If either operand is a :class:`float`, +classic division is performed and a :class:`float` is returned. The ``//`` +operator is also provided for doing floor division no matter what the +operands are. The remainder can be calculated with the ``%`` operator:: - >>> 17 / 3 # classic division returns a float - 5.666666666666667 - >>> - >>> 17 // 3 # floor division discards the fractional part + >>> 17 / 3 # int / int -> int 5 + >>> 17 / 3.0 # int / float -> float + 5.666666666666667 + >>> 17 // 3.0 # explicit floor division discards the fractional part + 5.0 >>> 17 % 3 # the % operator returns the remainder of the division 2 >>> 5 * 3 + 2 # result * divisor + remainder @@ -102,8 +104,10 @@ give you an error:: There is full support for floating point; operators with mixed type operands convert the integer operand to floating point:: - >>> 4 * 3.75 - 1 - 14.0 + >>> 3 * 3.75 / 1.5 + 7.5 + >>> 7.0 / 2 + 3.5 In interactive mode, the last printed expression is assigned to the variable ``_``. This means that when you are using Python as a desk calculator, it is @@ -157,18 +161,18 @@ special characters are escaped with backslashes. While this might sometimes look different from the input (the enclosing quotes could change), the two strings are equivalent. The string is enclosed in double quotes if the string contains a single quote and no double quotes, otherwise it is -enclosed in single quotes. The :func:`print` function produces a more +enclosed in single quotes. The :keyword:`print` statement produces a more readable output, by omitting the enclosing quotes and by printing escaped and special characters:: >>> '"Isn\'t," they said.' '"Isn\'t," they said.' - >>> print('"Isn\'t," they said.') + >>> print '"Isn\'t," they said.' "Isn't," they said. >>> s = 'First line.\nSecond line.' # \n means newline - >>> s # without print(), \n is included in the output + >>> s # without print, \n is included in the output 'First line.\nSecond line.' - >>> print(s) # with print(), \n produces a new line + >>> print s # with print, \n produces a new line First line. Second line. @@ -176,10 +180,10 @@ If you don't want characters prefaced by ``\`` to be interpreted as special characters, you can use *raw strings* by adding an ``r`` before the first quote:: - >>> print('C:\some\name') # here \n means newline! + >>> print 'C:\some\name' # here \n means newline! C:\some ame - >>> print(r'C:\some\name') # note the r before the quote + >>> print r'C:\some\name' # note the r before the quote C:\some\name String literals can span multiple lines. One way is using triple-quotes: @@ -187,11 +191,11 @@ String literals can span multiple lines. One way is using triple-quotes: included in the string, but it's possible to prevent this by adding a ``\`` at the end of the line. The following example:: - print("""\ + print """\ Usage: thingy [OPTIONS] -h Display this usage message -H hostname Hostname to connect to - """) + """ produces the following output (note that the initial newline is not included): @@ -225,14 +229,10 @@ This only works with two literals though, not with variables or expressions:: >>> prefix = 'Py' >>> prefix 'thon' # can't concatenate a variable and a string literal - File "<stdin>", line 1 - prefix 'thon' - ^ + ... SyntaxError: invalid syntax >>> ('un' * 3) 'ium' - File "<stdin>", line 1 - ('un' * 3) 'ium' - ^ + ... SyntaxError: invalid syntax If you want to concatenate variables or a variable and a literal, use ``+``:: @@ -262,7 +262,7 @@ Indices may also be negative numbers, to start counting from the right:: Note that since -0 is the same as 0, negative indices start from -1. In addition to indexing, *slicing* is also supported. While indexing is used -to obtain individual characters, *slicing* allows you to obtain substring:: +to obtain individual characters, *slicing* allows you to obtain a substring:: >>> word[0:2] # characters from position 0 (included) to 2 (excluded) 'Py' @@ -326,12 +326,10 @@ Python strings cannot be changed --- they are :term:`immutable`. Therefore, assigning to an indexed position in the string results in an error:: >>> word[0] = 'J' - Traceback (most recent call last): - File "<stdin>", line 1, in <module> + ... TypeError: 'str' object does not support item assignment >>> word[2:] = 'py' - Traceback (most recent call last): - File "<stdin>", line 1, in <module> + ... TypeError: 'str' object does not support item assignment If you need a different string, you should create a new one:: @@ -350,25 +348,121 @@ The built-in function :func:`len` returns the length of a string:: .. seealso:: - :ref:`textseq` - Strings are examples of *sequence types*, and support the common - operations supported by such types. + :ref:`typesseq` + Strings, and the Unicode strings described in the next section, are + examples of *sequence types*, and support the common operations supported + by such types. :ref:`string-methods` - Strings support a large number of methods for + Both strings and Unicode strings support a large number of methods for basic transformations and searching. - :ref:`f-strings` - String literals that have embedded expressions. - :ref:`formatstrings` Information about string formatting with :meth:`str.format`. - :ref:`old-string-formatting` - The old formatting operations invoked when strings are + :ref:`string-formatting` + The old formatting operations invoked when strings and Unicode strings are the left operand of the ``%`` operator are described in more detail here. +.. _tut-unicodestrings: + +Unicode Strings +--------------- + +.. sectionauthor:: Marc-Andre Lemburg <mal@lemburg.com> + + +Starting with Python 2.0 a new data type for storing text data is available to +the programmer: the Unicode object. It can be used to store and manipulate +Unicode data (see http://www.unicode.org/) and integrates well with the existing +string objects, providing auto-conversions where necessary. + +Unicode has the advantage of providing one ordinal for every character in every +script used in modern and ancient texts. Previously, there were only 256 +possible ordinals for script characters. Texts were typically bound to a code +page which mapped the ordinals to script characters. This lead to very much +confusion especially with respect to internationalization (usually written as +``i18n`` --- ``'i'`` + 18 characters + ``'n'``) of software. Unicode solves +these problems by defining one code page for all scripts. + +Creating Unicode strings in Python is just as simple as creating normal +strings:: + + >>> u'Hello World !' + u'Hello World !' + +The small ``'u'`` in front of the quote indicates that a Unicode string is +supposed to be created. If you want to include special characters in the string, +you can do so by using the Python *Unicode-Escape* encoding. The following +example shows how:: + + >>> u'Hello\u0020World !' + u'Hello World !' + +The escape sequence ``\u0020`` indicates to insert the Unicode character with +the ordinal value 0x0020 (the space character) at the given position. + +Other characters are interpreted by using their respective ordinal values +directly as Unicode ordinals. If you have literal strings in the standard +Latin-1 encoding that is used in many Western countries, you will find it +convenient that the lower 256 characters of Unicode are the same as the 256 +characters of Latin-1. + +For experts, there is also a raw mode just like the one for normal strings. You +have to prefix the opening quote with 'ur' to have Python use the +*Raw-Unicode-Escape* encoding. It will only apply the above ``\uXXXX`` +conversion if there is an uneven number of backslashes in front of the small +'u'. :: + + >>> ur'Hello\u0020World !' + u'Hello World !' + >>> ur'Hello\\u0020World !' + u'Hello\\\\u0020World !' + +The raw mode is most useful when you have to enter lots of backslashes, as can +be necessary in regular expressions. + +Apart from these standard encodings, Python provides a whole set of other ways +of creating Unicode strings on the basis of a known encoding. + +.. index:: builtin: unicode + +The built-in function :func:`unicode` provides access to all registered Unicode +codecs (COders and DECoders). Some of the more well known encodings which these +codecs can convert are *Latin-1*, *ASCII*, *UTF-8*, and *UTF-16*. The latter two +are variable-length encodings that store each Unicode character in one or more +bytes. The default encoding is normally set to ASCII, which passes through +characters in the range 0 to 127 and rejects any other characters with an error. +When a Unicode string is printed, written to a file, or converted with +:func:`str`, conversion takes place using this default encoding. :: + + >>> u"abc" + u'abc' + >>> str(u"abc") + 'abc' + >>> u"äöü" + u'\xe4\xf6\xfc' + >>> str(u"äöü") + Traceback (most recent call last): + File "<stdin>", line 1, in ? + UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128) + +To convert a Unicode string into an 8-bit string using a specific encoding, +Unicode objects provide an :func:`encode` method that takes one argument, the +name of the encoding. Lowercase names for encodings are preferred. :: + + >>> u"äöü".encode('utf-8') + '\xc3\xa4\xc3\xb6\xc3\xbc' + +If you have data in a specific encoding and want to produce a corresponding +Unicode string from it, you can use the :func:`unicode` function with the +encoding name as the second argument. :: + + >>> unicode('\xc3\xa4\xc3\xb6\xc3\xbc', 'utf-8') + u'\xe4\xf6\xfc' + + .. _tut-lists: Lists @@ -383,7 +477,7 @@ items of different types, but usually the items all have the same type. :: >>> squares [1, 4, 9, 16, 25] -Like strings (and all other built-in :term:`sequence` types), lists can be +Like strings (and all other built-in :term:`sequence` type), lists can be indexed and sliced:: >>> squares[0] # indexing returns the item @@ -394,13 +488,12 @@ indexed and sliced:: [9, 16, 25] All slice operations return a new list containing the requested elements. This -means that the following slice returns a -:ref:`shallow copy <shallow_vs_deep_copy>` of the list:: +means that the following slice returns a new (shallow) copy of the list:: >>> squares[:] [1, 4, 9, 16, 25] -Lists also support operations like concatenation:: +Lists also supports operations like concatenation:: >>> squares + [36, 49, 64, 81, 100] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] @@ -467,18 +560,16 @@ First Steps Towards Programming =============================== Of course, we can use Python for more complicated tasks than adding two and two -together. For instance, we can write an initial sub-sequence of the -`Fibonacci series <https://en.wikipedia.org/wiki/Fibonacci_number>`_ -as follows:: +together. For instance, we can write an initial sub-sequence of the *Fibonacci* +series as follows:: >>> # Fibonacci series: ... # the sum of two elements defines the next ... a, b = 0, 1 - >>> while a < 10: - ... print(a) + >>> while b < 10: + ... print b ... a, b = b, a+b ... - 0 1 1 2 @@ -494,7 +585,7 @@ This example introduces several new features. first before any of the assignments take place. The right-hand side expressions are evaluated from the left to the right. -* The :keyword:`while` loop executes as long as the condition (here: ``a < 10``) +* The :keyword:`while` loop executes as long as the condition (here: ``b < 10``) remains true. In Python, like in C, any non-zero integer value is true; zero is false. The condition may also be a string or list value, in fact any sequence; anything with a non-zero length is true, empty sequences are false. The test @@ -512,27 +603,27 @@ This example introduces several new features. guess when you have typed the last line). Note that each line within a basic block must be indented by the same amount. -* The :func:`print` function writes the value of the argument(s) it is given. - It differs from just writing the expression you want to write (as we did - earlier in the calculator examples) in the way it handles multiple arguments, - floating point quantities, and strings. Strings are printed without quotes, - and a space is inserted between items, so you can format things nicely, like - this:: +* The :keyword:`print` statement writes the value of the expression(s) it is + given. It differs from just writing the expression you want to write (as we did + earlier in the calculator examples) in the way it handles multiple expressions + and strings. Strings are printed without quotes, and a space is inserted + between items, so you can format things nicely, like this:: >>> i = 256*256 - >>> print('The value of i is', i) + >>> print 'The value of i is', i The value of i is 65536 - The keyword argument *end* can be used to avoid the newline after the output, - or end the output with a different string:: + A trailing comma avoids the newline after the output:: >>> a, b = 0, 1 - >>> while a < 1000: - ... print(a, end=',') + >>> while b < 1000: + ... print b, ... a, b = b, a+b ... - 0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987, + 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 + Note that the interpreter inserts a newline before it prints the next prompt if + the last line was not completed. .. rubric:: Footnotes diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst index af595e5..f767bb6 100644 --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -29,16 +29,15 @@ called :file:`fibo.py` in the current directory with the following contents:: def fib(n): # write Fibonacci series up to n a, b = 0, 1 - while a < n: - print(a, end=' ') + while b < n: + print b, a, b = b, a+b - print() def fib2(n): # return Fibonacci series up to n result = [] a, b = 0, 1 - while a < n: - result.append(a) + while b < n: + result.append(b) a, b = b, a+b return result @@ -52,9 +51,9 @@ the current symbol table; it only enters the module name ``fibo`` there. Using the module name you can access the functions:: >>> fibo.fib(1000) - 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 + 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 >>> fibo.fib2(100) - [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] + [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] >>> fibo.__name__ 'fibo' @@ -62,7 +61,7 @@ If you intend to use a function often you can assign it to a local name:: >>> fib = fibo.fib >>> fib(500) - 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 + 1 1 2 3 5 8 13 21 34 55 89 144 233 377 .. _tut-moremodules: @@ -92,7 +91,7 @@ module directly into the importing module's symbol table. For example:: >>> from fibo import fib, fib2 >>> fib(500) - 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 + 1 1 2 3 5 8 13 21 34 55 89 144 233 377 This does not introduce the module name from which the imports are taken in the local symbol table (so in the example, ``fibo`` is not defined). @@ -101,19 +100,16 @@ There is even a variant to import all names that a module defines:: >>> from fibo import * >>> fib(500) - 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 + 1 1 2 3 5 8 13 21 34 55 89 144 233 377 This imports all names except those beginning with an underscore (``_``). -In most cases Python programmers do not use this facility since it introduces -an unknown set of names into the interpreter, possibly hiding some things -you have already defined. Note that in general the practice of importing ``*`` from a module or package is frowned upon, since it often causes poorly readable code. However, it is okay to use it to save typing in interactive sessions. -If the module name is followed by :keyword:`!as`, then the name -following :keyword:`!as` is bound directly to the imported module. +If the module name is followed by :keyword:`as`, then the name +following :keyword:`as` is bound directly to the imported module. :: @@ -136,8 +132,7 @@ It can also be used when utilising :keyword:`from` with similar effects:: For efficiency reasons, each module is only imported once per interpreter session. Therefore, if you change your modules, you must restart the interpreter -- or, if it's just one module you want to test interactively, - use :func:`importlib.reload`, e.g. ``import importlib; - importlib.reload(modulename)``. + use :func:`reload`, e.g. ``reload(modulename)``. .. _tut-modulesasscripts: @@ -164,7 +159,7 @@ executed as the "main" file: .. code-block:: shell-session $ python fibo.py 50 - 0 1 1 2 3 5 8 13 21 34 + 1 1 2 3 5 8 13 21 34 If the module is imported, the code is not run:: @@ -187,16 +182,10 @@ a built-in module with that name. If not found, it then searches for a file named :file:`spam.py` in a list of directories given by the variable :data:`sys.path`. :data:`sys.path` is initialized from these locations: -* The directory containing the input script (or the current directory when no - file is specified). +* the directory containing the input script (or the current directory). * :envvar:`PYTHONPATH` (a list of directory names, with the same syntax as the shell variable :envvar:`PATH`). -* The installation-dependent default. - -.. note:: - On file systems which support symlinks, the directory containing the input - script is calculated after the symlink is followed. In other words the - directory containing the symlink is **not** added to the module search path. +* the installation-dependent default. After initialization, Python programs can modify :data:`sys.path`. The directory containing the script being run is placed at the beginning of the @@ -205,51 +194,61 @@ directory will be loaded instead of modules of the same name in the library directory. This is an error unless the replacement is intended. See section :ref:`tut-standardmodules` for more information. -.. % - Do we need stuff on zip files etc. ? DUBOIS "Compiled" Python files ----------------------- -To speed up loading modules, Python caches the compiled version of each module -in the ``__pycache__`` directory under the name :file:`module.{version}.pyc`, -where the version encodes the format of the compiled file; it generally contains -the Python version number. For example, in CPython release 3.3 the compiled -version of spam.py would be cached as ``__pycache__/spam.cpython-33.pyc``. This -naming convention allows compiled modules from different releases and different -versions of Python to coexist. - -Python checks the modification date of the source against the compiled version -to see if it's out of date and needs to be recompiled. This is a completely -automatic process. Also, the compiled modules are platform-independent, so the -same library can be shared among systems with different architectures. - -Python does not check the cache in two circumstances. First, it always -recompiles and does not store the result for the module that's loaded directly -from the command line. Second, it does not check the cache if there is no -source module. To support a non-source (compiled only) distribution, the -compiled module must be in the source directory, and there must not be a source -module. +As an important speed-up of the start-up time for short programs that use a lot +of standard modules, if a file called :file:`spam.pyc` exists in the directory +where :file:`spam.py` is found, this is assumed to contain an +already-"byte-compiled" version of the module :mod:`spam`. The modification time +of the version of :file:`spam.py` used to create :file:`spam.pyc` is recorded in +:file:`spam.pyc`, and the :file:`.pyc` file is ignored if these don't match. + +Normally, you don't need to do anything to create the :file:`spam.pyc` file. +Whenever :file:`spam.py` is successfully compiled, an attempt is made to write +the compiled version to :file:`spam.pyc`. It is not an error if this attempt +fails; if for any reason the file is not written completely, the resulting +:file:`spam.pyc` file will be recognized as invalid and thus ignored later. The +contents of the :file:`spam.pyc` file are platform independent, so a Python +module directory can be shared by machines of different architectures. Some tips for experts: -* You can use the :option:`-O` or :option:`-OO` switches on the Python command - to reduce the size of a compiled module. The ``-O`` switch removes assert - statements, the ``-OO`` switch removes both assert statements and __doc__ - strings. Since some programs may rely on having these available, you should - only use this option if you know what you're doing. "Optimized" modules have - an ``opt-`` tag and are usually smaller. Future releases may - change the effects of optimization. +* When the Python interpreter is invoked with the :option:`-O` flag, optimized + code is generated and stored in :file:`.pyo` files. The optimizer currently + doesn't help much; it only removes :keyword:`assert` statements. When + :option:`-O` is used, *all* :term:`bytecode` is optimized; ``.pyc`` files are + ignored and ``.py`` files are compiled to optimized bytecode. + +* Passing two :option:`-O` flags to the Python interpreter (:option:`-OO`) will + cause the bytecode compiler to perform optimizations that could in some rare + cases result in malfunctioning programs. Currently only ``__doc__`` strings are + removed from the bytecode, resulting in more compact :file:`.pyo` files. Since + some programs may rely on having these available, you should only use this + option if you know what you're doing. -* A program doesn't run any faster when it is read from a ``.pyc`` - file than when it is read from a ``.py`` file; the only thing that's faster - about ``.pyc`` files is the speed with which they are loaded. +* A program doesn't run any faster when it is read from a :file:`.pyc` or + :file:`.pyo` file than when it is read from a :file:`.py` file; the only thing + that's faster about :file:`.pyc` or :file:`.pyo` files is the speed with which + they are loaded. -* The module :mod:`compileall` can create .pyc files for all modules in a - directory. +* When a script is run by giving its name on the command line, the bytecode for + the script is never written to a :file:`.pyc` or :file:`.pyo` file. Thus, the + startup time of a script may be reduced by moving most of its code to a module + and having a small bootstrap script that imports that module. It is also + possible to name a :file:`.pyc` or :file:`.pyo` file directly on the command + line. -* There is more detail on this process, including a flow chart of the - decisions, in :pep:`3147`. +* It is possible to have a file called :file:`spam.pyc` (or :file:`spam.pyo` + when :option:`-O` is used) without a file :file:`spam.py` for the same module. + This can be used to distribute a library of Python code in a form that is + moderately hard to reverse engineer. + + .. index:: module: compileall + +* The module :mod:`compileall` can create :file:`.pyc` files (or :file:`.pyo` + files when :option:`-O` is used) for all modules in a directory. .. _tut-standardmodules: @@ -277,7 +276,7 @@ prompts:: >>> sys.ps2 '... ' >>> sys.ps1 = 'C> ' - C> print('Yuck!') + C> print 'Yuck!' Yuck! C> @@ -306,27 +305,21 @@ defines. It returns a sorted list of strings:: >>> dir(fibo) ['__name__', 'fib', 'fib2'] >>> dir(sys) # doctest: +NORMALIZE_WHITESPACE - ['__breakpointhook__', '__displayhook__', '__doc__', '__excepthook__', - '__interactivehook__', '__loader__', '__name__', '__package__', '__spec__', - '__stderr__', '__stdin__', '__stdout__', '__unraisablehook__', - '_clear_type_cache', '_current_frames', '_debugmallocstats', '_framework', - '_getframe', '_git', '_home', '_xoptions', 'abiflags', 'addaudithook', - 'api_version', 'argv', 'audit', 'base_exec_prefix', 'base_prefix', - 'breakpointhook', 'builtin_module_names', 'byteorder', 'call_tracing', - 'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info', - 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', - 'float_repr_style', 'get_asyncgen_hooks', 'get_coroutine_origin_tracking_depth', - 'getallocatedblocks', 'getdefaultencoding', 'getdlopenflags', - 'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile', - 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', - 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info', - 'intern', 'is_finalizing', 'last_traceback', 'last_type', 'last_value', - 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', - 'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'pycache_prefix', - 'set_asyncgen_hooks', 'set_coroutine_origin_tracking_depth', 'setdlopenflags', - 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', - 'stdin', 'stdout', 'thread_info', 'unraisablehook', 'version', 'version_info', - 'warnoptions'] + ['__displayhook__', '__doc__', '__excepthook__', '__name__', '__package__', + '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', + '_current_frames', '_getframe', '_mercurial', 'api_version', 'argv', + 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', + 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_clear', 'exc_info', + 'exc_traceback', 'exc_type', 'exc_value', 'excepthook', 'exec_prefix', + 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', + 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', + 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit', + 'getrefcount', 'getsizeof', 'gettotalrefcount', 'gettrace', 'hexversion', + 'long_info', 'maxint', 'maxsize', 'maxunicode', 'meta_path', 'modules', + 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', + 'py3kwarning', 'setcheckinterval', 'setdlopenflags', 'setprofile', + 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', + 'version', 'version_info', 'warnoptions'] Without arguments, :func:`dir` lists the names you have defined currently:: @@ -334,47 +327,45 @@ Without arguments, :func:`dir` lists the names you have defined currently:: >>> import fibo >>> fib = fibo.fib >>> dir() - ['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys'] + ['__builtins__', '__name__', '__package__', 'a', 'fib', 'fibo', 'sys'] Note that it lists all types of names: variables, modules, functions, etc. -.. index:: module: builtins +.. index:: module: __builtin__ :func:`dir` does not list the names of built-in functions and variables. If you want a list of those, they are defined in the standard module -:mod:`builtins`:: +:mod:`__builtin__`:: - >>> import builtins - >>> dir(builtins) # doctest: +NORMALIZE_WHITESPACE + >>> import __builtin__ + >>> dir(__builtin__) # doctest: +NORMALIZE_WHITESPACE ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', - 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', - 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', - 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', - 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', - 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', - 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', - 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', - 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', - 'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', + 'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError', + 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', + 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', + 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', + 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', - 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', - 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', - 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', - 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', - 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', - 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', - 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__', - '__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs', - 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', - 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', - 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', - 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', - 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', - 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', - 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', - 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', - 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', - 'zip'] + 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', + 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', + 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', + 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', + 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', + 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', + 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__', + '__name__', '__package__', 'abs', 'all', 'any', 'apply', 'basestring', + 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', + 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', + 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', + 'execfile', 'exit', 'file', 'filter', 'float', 'format', 'frozenset', + 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', + 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', + 'list', 'locals', 'long', 'map', 'max', 'memoryview', 'min', 'next', + 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', + 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', + 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', + 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip'] + .. _tut-packages: @@ -429,9 +420,9 @@ your package (expressed in terms of a hierarchical filesystem): When importing the package, Python searches through the directories on ``sys.path`` looking for the package subdirectory. -The :file:`__init__.py` files are required to make Python treat directories -containing the file as packages. This prevents directories with a common name, -such as ``string``, unintentionally hiding valid modules that occur later +The :file:`__init__.py` files are required to make Python treat the directories +as containing packages; this is done to prevent directories with a common name, +such as ``string``, from unintentionally hiding valid modules that occur later on the module search path. In the simplest case, :file:`__init__.py` can just be an empty file, but it can also execute initialization code for the package or set the ``__all__`` variable, described later. @@ -536,24 +527,35 @@ packages. Intra-package References ------------------------ +The submodules often need to refer to each other. For example, the +:mod:`surround` module might use the :mod:`echo` module. In fact, such +references are so common that the :keyword:`import` statement first looks in the +containing package before looking in the standard module search path. Thus, the +:mod:`surround` module can simply use ``import echo`` or ``from echo import +echofilter``. If the imported module is not found in the current package (the +package of which the current module is a submodule), the :keyword:`import` +statement looks for a top-level module with the given name. + When packages are structured into subpackages (as with the :mod:`sound` package in the example), you can use absolute imports to refer to submodules of siblings packages. For example, if the module :mod:`sound.filters.vocoder` needs to use the :mod:`echo` module in the :mod:`sound.effects` package, it can use ``from sound.effects import echo``. -You can also write relative imports, with the ``from module import name`` form -of import statement. These imports use leading dots to indicate the current and -parent packages involved in the relative import. From the :mod:`surround` -module for example, you might use:: +Starting with Python 2.5, in addition to the implicit relative imports described +above, you can write explicit relative imports with the ``from module import +name`` form of import statement. These explicit relative imports use leading +dots to indicate the current and parent packages involved in the relative +import. From the :mod:`surround` module for example, you might use:: from . import echo from .. import formats from ..filters import equalizer -Note that relative imports are based on the name of the current module. Since -the name of the main module is always ``"__main__"``, modules intended for use -as the main module of a Python application must always use absolute imports. +Note that both explicit and implicit relative imports are based on the name of +the current module. Since the name of the main module is always ``"__main__"``, +modules intended for use as the main module of a Python application should +always use absolute imports. Packages in Multiple Directories @@ -574,3 +576,4 @@ modules found in a package. .. [#] In fact function definitions are also 'statements' that are 'executed'; the execution of a module-level function definition enters the function name in the module's global symbol table. + diff --git a/Doc/tutorial/stdlib.rst b/Doc/tutorial/stdlib.rst index a52653b..4dab074 100644 --- a/Doc/tutorial/stdlib.rst +++ b/Doc/tutorial/stdlib.rst @@ -15,7 +15,7 @@ operating system:: >>> import os >>> os.getcwd() # Return the current working directory - 'C:\\Python39' + 'C:\\Python26' >>> os.chdir('/server/accesslogs') # Change current working directory >>> os.system('mkdir today') # Run the command mkdir in the system shell 0 @@ -40,9 +40,7 @@ a higher level interface that is easier to use:: >>> import shutil >>> shutil.copyfile('data.db', 'archive.db') - 'archive.db' >>> shutil.move('/build/executables', 'installdir') - 'installdir' .. _tut-file-wildcards: @@ -69,25 +67,12 @@ instance the following output results from running ``python demo.py one two three`` at the command line:: >>> import sys - >>> print(sys.argv) + >>> print sys.argv ['demo.py', 'one', 'two', 'three'] -The :mod:`argparse` module provides a more sophisticated mechanism to process -command line arguments. The following script extracts one or more filenames -and an optional number of lines to be displayed:: - - import argparse - - parser = argparse.ArgumentParser(prog = 'top', - description = 'Show top lines from each file') - parser.add_argument('filenames', nargs='+') - parser.add_argument('-l', '--lines', type=int, default=10) - args = parser.parse_args() - print(args) - -When run at the command line with ``python top.py --lines=5 alpha.txt -beta.txt``, the script sets ``args.lines`` to ``5`` and ``args.filenames`` -to ``['alpha.txt', 'beta.txt']``. +The :mod:`getopt` module processes *sys.argv* using the conventions of the Unix +:func:`getopt` function. More powerful and flexible command line processing is +provided by the :mod:`argparse` module. .. _tut-stderr: @@ -136,7 +121,7 @@ The :mod:`math` module gives access to the underlying C library functions for floating point math:: >>> import math - >>> math.cos(math.pi / 4) + >>> math.cos(math.pi / 4.0) 0.70710678118654757 >>> math.log(1024, 2) 10.0 @@ -146,27 +131,13 @@ The :mod:`random` module provides tools for making random selections:: >>> import random >>> random.choice(['apple', 'pear', 'banana']) 'apple' - >>> random.sample(range(100), 10) # sampling without replacement + >>> random.sample(xrange(100), 10) # sampling without replacement [30, 83, 16, 4, 8, 81, 41, 50, 18, 33] >>> random.random() # random float 0.17970987693706186 >>> random.randrange(6) # random integer chosen from range(6) 4 -The :mod:`statistics` module calculates basic statistical properties -(the mean, median, variance, etc.) of numeric data:: - - >>> import statistics - >>> data = [2.75, 1.75, 1.25, 0.25, 0.5, 1.25, 3.5] - >>> statistics.mean(data) - 1.6071428571428572 - >>> statistics.median(data) - 1.25 - >>> statistics.variance(data) - 1.3720238095238095 - -The SciPy project <https://scipy.org> has many other modules for numerical -computations. .. _tut-internet-access: @@ -174,15 +145,13 @@ Internet Access =============== There are a number of modules for accessing the internet and processing internet -protocols. Two of the simplest are :mod:`urllib.request` for retrieving data -from URLs and :mod:`smtplib` for sending mail:: +protocols. Two of the simplest are :mod:`urllib2` for retrieving data from URLs +and :mod:`smtplib` for sending mail:: - >>> from urllib.request import urlopen - >>> with urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl') as response: - ... for line in response: - ... line = line.decode('utf-8') # Decoding the binary data to text. - ... if 'EST' in line or 'EDT' in line: # look for Eastern Time - ... print(line) + >>> import urllib2 + >>> for line in urllib2.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'): + ... if 'EST' in line or 'EDT' in line: # look for Eastern Time + ... print line <BR>Nov. 25, 09:43:32 PM EST @@ -231,18 +200,18 @@ Data Compression ================ Common data archiving and compression formats are directly supported by modules -including: :mod:`zlib`, :mod:`gzip`, :mod:`bz2`, :mod:`lzma`, :mod:`zipfile` and +including: :mod:`zlib`, :mod:`gzip`, :mod:`bz2`, :mod:`zipfile` and :mod:`tarfile`. :: >>> import zlib - >>> s = b'witch which has which witches wrist watch' + >>> s = 'witch which has which witches wrist watch' >>> len(s) 41 >>> t = zlib.compress(s) >>> len(t) 37 >>> zlib.decompress(t) - b'witch which has which witches wrist watch' + 'witch which has which witches wrist watch' >>> zlib.crc32(s) 226805979 @@ -290,10 +259,10 @@ documentation:: def average(values): """Computes the arithmetic mean of a list of numbers. - >>> print(average([20, 30, 70])) + >>> print average([20, 30, 70]) 40.0 """ - return sum(values) / len(values) + return sum(values, 0.0) / len(values) import doctest doctest.testmod() # automatically validate the embedded tests @@ -325,29 +294,24 @@ Batteries Included Python has a "batteries included" philosophy. This is best seen through the sophisticated and robust capabilities of its larger packages. For example: -* The :mod:`xmlrpc.client` and :mod:`xmlrpc.server` modules make implementing +* The :mod:`xmlrpclib` and :mod:`SimpleXMLRPCServer` modules make implementing remote procedure calls into an almost trivial task. Despite the modules names, no direct knowledge or handling of XML is needed. * The :mod:`email` package is a library for managing email messages, including - MIME and other :rfc:`2822`-based message documents. Unlike :mod:`smtplib` and + MIME and other RFC 2822-based message documents. Unlike :mod:`smtplib` and :mod:`poplib` which actually send and receive messages, the email package has a complete toolset for building or decoding complex message structures (including attachments) and for implementing internet encoding and header protocols. -* The :mod:`json` package provides robust support for parsing this - popular data interchange format. The :mod:`csv` module supports - direct reading and writing of files in Comma-Separated Value format, - commonly supported by databases and spreadsheets. XML processing is - supported by the :mod:`xml.etree.ElementTree`, :mod:`xml.dom` and - :mod:`xml.sax` packages. Together, these modules and packages - greatly simplify data interchange between Python applications and - other tools. - -* The :mod:`sqlite3` module is a wrapper for the SQLite database - library, providing a persistent database that can be updated and - accessed using slightly nonstandard SQL syntax. +* The :mod:`xml.dom` and :mod:`xml.sax` packages provide robust support for + parsing this popular data interchange format. Likewise, the :mod:`csv` module + supports direct reads and writes in a common database format. Together, these + modules and packages greatly simplify data interchange between Python + applications and other tools. * Internationalization is supported by a number of modules including :mod:`gettext`, :mod:`locale`, and the :mod:`codecs` package. + + diff --git a/Doc/tutorial/stdlib2.rst b/Doc/tutorial/stdlib2.rst index 2994828..22c2a4f 100644 --- a/Doc/tutorial/stdlib2.rst +++ b/Doc/tutorial/stdlib2.rst @@ -13,12 +13,12 @@ programming needs. These modules rarely occur in small scripts. Output Formatting ================= -The :mod:`reprlib` module provides a version of :func:`repr` customized for +The :mod:`repr` module provides a version of :func:`repr` customized for abbreviated displays of large or deeply nested containers:: - >>> import reprlib - >>> reprlib.repr(set('supercalifragilisticexpialidocious')) - "{'a', 'c', 'd', 'e', 'f', 'g', ...}" + >>> import repr + >>> repr.repr(set('supercalifragilisticexpialidocious')) + "set(['a', 'c', 'd', 'e', 'f', 'g', ...])" The :mod:`pprint` module offers more sophisticated control over printing both built-in and user defined objects in a way that is readable by the interpreter. @@ -44,7 +44,7 @@ width:: ... a list of strings instead of one big string with newlines to separate ... the wrapped lines.""" ... - >>> print(textwrap.fill(doc, width=40)) + >>> print textwrap.fill(doc, width=40) The wrap() method is just like fill() except that it returns a list of strings instead of one big string with newlines @@ -108,7 +108,7 @@ placeholders such as the current date, image sequence number, or file format:: >>> photofiles = ['img_1074.jpg', 'img_1076.jpg', 'img_1077.jpg'] >>> class BatchRename(Template): ... delimiter = '%' - >>> fmt = input('Enter rename style (%d-date %n-seqnum %f-format): ') + >>> fmt = raw_input('Enter rename style (%d-date %n-seqnum %f-format): ') Enter rename style (%d-date %n-seqnum %f-format): Ashley_%n%f >>> t = BatchRename(fmt) @@ -116,7 +116,7 @@ placeholders such as the current date, image sequence number, or file format:: >>> for i, filename in enumerate(photofiles): ... base, ext = os.path.splitext(filename) ... newname = t.substitute(d=date, n=i, f=ext) - ... print('{0} --> {1}'.format(filename, newname)) + ... print '{0} --> {1}'.format(filename, newname) img_1074.jpg --> Ashley_0.jpg img_1076.jpg --> Ashley_1.jpg @@ -142,9 +142,7 @@ standard size and in little-endian byte order:: import struct - with open('myfile.zip', 'rb') as f: - data = f.read() - + data = open('myfile.zip', 'rb').read() start = 0 for i in range(3): # show the first 3 file headers start += 14 @@ -155,7 +153,7 @@ standard size and in little-endian byte order:: filename = data[start:start+filenamesize] start += filenamesize extra = data[start:start+extra_size] - print(filename, hex(crc32), comp_size, uncomp_size) + print filename, hex(crc32), comp_size, uncomp_size start += extra_size + comp_size # skip to the next header @@ -185,14 +183,14 @@ tasks in background while the main program continues to run:: f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED) f.write(self.infile) f.close() - print('Finished background zip of:', self.infile) + print 'Finished background zip of: ', self.infile background = AsyncZip('mydata.txt', 'myarchive.zip') background.start() - print('The main program continues to run in foreground.') + print 'The main program continues to run in foreground.' background.join() # Wait for the background task to finish - print('Main program waited until background was done.') + print 'Main program waited until background was done.' The principal challenge of multi-threaded applications is coordinating threads that share data or other resources. To that end, the threading module provides @@ -202,9 +200,9 @@ variables, and semaphores. While those tools are powerful, minor design errors can result in problems that are difficult to reproduce. So, the preferred approach to task coordination is to concentrate all access to a resource in a single thread and then use the -:mod:`queue` module to feed that thread with requests from other threads. -Applications using :class:`~queue.Queue` objects for inter-thread communication and -coordination are easier to design, more readable, and more reliable. +:mod:`Queue` module to feed that thread with requests from other threads. +Applications using :class:`Queue.Queue` objects for inter-thread communication +and coordination are easier to design, more readable, and more reliable. .. _tut-logging: @@ -278,7 +276,7 @@ applications include caching objects that are expensive to create:: Traceback (most recent call last): File "<stdin>", line 1, in <module> d['primary'] # entry was automatically removed - File "C:/python39/lib/weakref.py", line 46, in __getitem__ + File "C:/python26/lib/weakref.py", line 46, in __getitem__ o = self.data[key]() KeyError: 'primary' @@ -313,7 +311,7 @@ and breadth first tree searches:: >>> from collections import deque >>> d = deque(["task1", "task2", "task3"]) >>> d.append("task4") - >>> print("Handling", d.popleft()) + >>> print "Handling", d.popleft() Handling task1 :: @@ -371,9 +369,12 @@ results in decimal floating point and binary floating point. The difference becomes significant if the results are rounded to the nearest cent:: >>> from decimal import * - >>> round(Decimal('0.70') * Decimal('1.05'), 2) + >>> x = Decimal('0.70') * Decimal('1.05') + >>> x + Decimal('0.7350') + >>> x.quantize(Decimal('0.01')) # round to nearest cent Decimal('0.74') - >>> round(.70 * 1.05, 2) + >>> round(.70 * 1.05, 2) # same calculation with floats 0.73 The :class:`~decimal.Decimal` result keeps a trailing zero, automatically diff --git a/Doc/tutorial/venv.rst b/Doc/tutorial/venv.rst deleted file mode 100644 index f422146..0000000 --- a/Doc/tutorial/venv.rst +++ /dev/null @@ -1,216 +0,0 @@ - -.. _tut-venv: - -********************************* -Virtual Environments and Packages -********************************* - -Introduction -============ - -Python applications will often use packages and modules that don't -come as part of the standard library. Applications will sometimes -need a specific version of a library, because the application may -require that a particular bug has been fixed or the application may be -written using an obsolete version of the library's interface. - -This means it may not be possible for one Python installation to meet -the requirements of every application. If application A needs version -1.0 of a particular module but application B needs version 2.0, then -the requirements are in conflict and installing either version 1.0 or 2.0 -will leave one application unable to run. - -The solution for this problem is to create a :term:`virtual environment`, a -self-contained directory tree that contains a Python installation for a -particular version of Python, plus a number of additional packages. - -Different applications can then use different virtual environments. -To resolve the earlier example of conflicting requirements, -application A can have its own virtual environment with version 1.0 -installed while application B has another virtual environment with version 2.0. -If application B requires a library be upgraded to version 3.0, this will -not affect application A's environment. - - -Creating Virtual Environments -============================= - -The module used to create and manage virtual environments is called -:mod:`venv`. :mod:`venv` will usually install the most recent version of -Python that you have available. If you have multiple versions of Python on your -system, you can select a specific Python version by running ``python3`` or -whichever version you want. - -To create a virtual environment, decide upon a directory where you want to -place it, and run the :mod:`venv` module as a script with the directory path:: - - python3 -m venv tutorial-env - -This will create the ``tutorial-env`` directory if it doesn't exist, -and also create directories inside it containing a copy of the Python -interpreter, the standard library, and various supporting files. - -A common directory location for a virtual environment is ``.venv``. -This name keeps the directory typically hidden in your shell and thus -out of the way while giving it a name that explains why the directory -exists. It also prevents clashing with ``.env`` environment variable -definition files that some tooling supports. - -Once you've created a virtual environment, you may activate it. - -On Windows, run:: - - tutorial-env\Scripts\activate.bat - -On Unix or MacOS, run:: - - source tutorial-env/bin/activate - -(This script is written for the bash shell. If you use the -:program:`csh` or :program:`fish` shells, there are alternate -``activate.csh`` and ``activate.fish`` scripts you should use -instead.) - -Activating the virtual environment will change your shell's prompt to show what -virtual environment you're using, and modify the environment so that running -``python`` will get you that particular version and installation of Python. -For example: - -.. code-block:: bash - - $ source ~/envs/tutorial-env/bin/activate - (tutorial-env) $ python - Python 3.5.1 (default, May 6 2016, 10:59:36) - ... - >>> import sys - >>> sys.path - ['', '/usr/local/lib/python35.zip', ..., - '~/envs/tutorial-env/lib/python3.5/site-packages'] - >>> - - -Managing Packages with pip -========================== - -You can install, upgrade, and remove packages using a program called -:program:`pip`. By default ``pip`` will install packages from the Python -Package Index, <https://pypi.org>. You can browse the Python -Package Index by going to it in your web browser, or you can use ``pip``'s -limited search feature: - -.. code-block:: bash - - (tutorial-env) $ pip search astronomy - skyfield - Elegant astronomy for Python - gary - Galactic astronomy and gravitational dynamics. - novas - The United States Naval Observatory NOVAS astronomy library - astroobs - Provides astronomy ephemeris to plan telescope observations - PyAstronomy - A collection of astronomy related tools for Python. - ... - -``pip`` has a number of subcommands: "search", "install", "uninstall", -"freeze", etc. (Consult the :ref:`installing-index` guide for -complete documentation for ``pip``.) - -You can install the latest version of a package by specifying a package's name: - -.. code-block:: bash - - (tutorial-env) $ python -m pip install novas - Collecting novas - Downloading novas-3.1.1.3.tar.gz (136kB) - Installing collected packages: novas - Running setup.py install for novas - Successfully installed novas-3.1.1.3 - -You can also install a specific version of a package by giving the -package name followed by ``==`` and the version number: - -.. code-block:: bash - - (tutorial-env) $ python -m pip install requests==2.6.0 - Collecting requests==2.6.0 - Using cached requests-2.6.0-py2.py3-none-any.whl - Installing collected packages: requests - Successfully installed requests-2.6.0 - -If you re-run this command, ``pip`` will notice that the requested -version is already installed and do nothing. You can supply a -different version number to get that version, or you can run ``pip -install --upgrade`` to upgrade the package to the latest version: - -.. code-block:: bash - - (tutorial-env) $ python -m pip install --upgrade requests - Collecting requests - Installing collected packages: requests - Found existing installation: requests 2.6.0 - Uninstalling requests-2.6.0: - Successfully uninstalled requests-2.6.0 - Successfully installed requests-2.7.0 - -``pip uninstall`` followed by one or more package names will remove the -packages from the virtual environment. - -``pip show`` will display information about a particular package: - -.. code-block:: bash - - (tutorial-env) $ pip show requests - --- - Metadata-Version: 2.0 - Name: requests - Version: 2.7.0 - Summary: Python HTTP for Humans. - Home-page: http://python-requests.org - Author: Kenneth Reitz - Author-email: me@kennethreitz.com - License: Apache 2.0 - Location: /Users/akuchling/envs/tutorial-env/lib/python3.4/site-packages - Requires: - -``pip list`` will display all of the packages installed in the virtual -environment: - -.. code-block:: bash - - (tutorial-env) $ pip list - novas (3.1.1.3) - numpy (1.9.2) - pip (7.0.3) - requests (2.7.0) - setuptools (16.0) - -``pip freeze`` will produce a similar list of the installed packages, -but the output uses the format that ``pip install`` expects. -A common convention is to put this list in a ``requirements.txt`` file: - -.. code-block:: bash - - (tutorial-env) $ pip freeze > requirements.txt - (tutorial-env) $ cat requirements.txt - novas==3.1.1.3 - numpy==1.9.2 - requests==2.7.0 - -The ``requirements.txt`` can then be committed to version control and -shipped as part of an application. Users can then install all the -necessary packages with ``install -r``: - -.. code-block:: bash - - (tutorial-env) $ python -m pip install -r requirements.txt - Collecting novas==3.1.1.3 (from -r requirements.txt (line 1)) - ... - Collecting numpy==1.9.2 (from -r requirements.txt (line 2)) - ... - Collecting requests==2.7.0 (from -r requirements.txt (line 3)) - ... - Installing collected packages: novas, numpy, requests - Running setup.py install for novas - Successfully installed novas-3.1.1.3 numpy-1.9.2 requests-2.7.0 - -``pip`` has many more options. Consult the :ref:`installing-index` -guide for complete documentation for ``pip``. When you've written -a package and want to make it available on the Python Package Index, -consult the :ref:`distributing-index` guide. diff --git a/Doc/tutorial/whatnow.rst b/Doc/tutorial/whatnow.rst index 3208201..f6ce4f4 100644 --- a/Doc/tutorial/whatnow.rst +++ b/Doc/tutorial/whatnow.rst @@ -21,8 +21,8 @@ the set are: and many other tasks. Skimming through the Library Reference will give you an idea of what's available. -* :ref:`installing-index` explains how to install additional modules written - by other Python users. +* :ref:`install-index` explains how to install external modules written by other + Python users. * :ref:`reference-index`: A detailed explanation of Python's syntax and semantics. It's heavy reading, but is useful as a complete guide to the @@ -39,7 +39,7 @@ More Python resources: * https://docs.python.org: Fast access to Python's documentation. * https://pypi.org: The Python Package Index, previously also nicknamed - the Cheese Shop [#]_, is an index of user-created Python modules that are available + the Cheese Shop, is an index of user-created Python modules that are available for download. Once you begin releasing code, you can register it here so that others can find it. @@ -48,29 +48,20 @@ More Python resources: Particularly notable contributions are collected in a book also titled Python Cookbook (O'Reilly & Associates, ISBN 0-596-00797-3.) -* http://www.pyvideo.org collects links to Python-related videos from - conferences and user-group meetings. - -* https://scipy.org: The Scientific Python project includes modules for fast - array computations and manipulations plus a host of packages for such - things as linear algebra, Fourier transforms, non-linear solvers, - random number distributions, statistical analysis and the like. - For Python-related questions and problem reports, you can post to the newsgroup :newsgroup:`comp.lang.python`, or send them to the mailing list at python-list@python.org. The newsgroup and mailing list are gatewayed, so messages posted to one will automatically be forwarded to the other. There are -hundreds of postings a day, asking (and +around 120 postings a day (with peaks up to several hundred), asking (and answering) questions, suggesting new features, and announcing new modules. -Mailing list archives are available at https://mail.python.org/pipermail/. - -Before posting, be sure to check the list of -:ref:`Frequently Asked Questions <faq-index>` (also called the FAQ). The -FAQ answers many of the questions that come up again and again, and may -already contain the solution for your problem. +Before posting, be sure to check the list of :ref:`Frequently Asked Questions +<faq-index>` (also called the FAQ). Mailing list +archives are available at https://mail.python.org/pipermail/. The FAQ answers +many of the questions that come up again and again, and may already contain the +solution for your problem. -.. rubric:: Footnotes +.. Postings figure based on average of last six months activity as + reported by www.egroups.com; Jan. 2000 - June 2000: 21272 msgs / 182 + days = 116.9 msgs / day and steadily increasing. (XXX up to date figures?) -.. [#] "Cheese Shop" is a Monty Python's sketch: a customer enters a cheese shop, - but whatever cheese he asks for, the clerk says it's missing. |