Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Doc/howto/doanddont.rst

    r2 r391  
    3333valid, no more than having a smart lawyer makes a man innocent. Do not use it
    3434like that ever. Even in versions where it was accepted, it made the function
    35 execution slower, because the compiler could not be certain which names are
    36 local and which are global. In Python 2.1 this construct causes warnings, and
     35execution slower, because the compiler could not be certain which names were
     36local and which were global. In Python 2.1 this construct causes warnings, and
    3737sometimes even errors.
    3838
     
    4747some module grows additional functions or classes.
    4848
    49 One of the most awful question asked on the newsgroup is why this code::
     49One of the most awful questions asked on the newsgroup is why this code::
    5050
    5151   f = open("www")
     
    114114This is a "don't" which is much weaker than the previous "don't"s but is still
    115115something you should not do if you don't have good reasons to do that. The
    116 reason it is usually bad idea is because you suddenly have an object which lives
     116reason it is usually a bad idea is because you suddenly have an object which lives
    117117in two separate namespaces. When the binding in one namespace changes, the
    118118binding in the other will not, so there will be a discrepancy between them. This
     
    145145
    146146Python has the ``except:`` clause, which catches all exceptions. Since *every*
    147 error in Python raises an exception, this makes many programming errors look
    148 like runtime problems, and hinders the debugging process.
    149 
    150 The following code shows a great example::
     147error in Python raises an exception, using ``except:`` can make many
     148programming errors look like runtime problems, which hinders the debugging
     149process.
     150
     151The following code shows a great example of why this is bad::
    151152
    152153   try:
     
    155156       sys.exit("could not open file!")
    156157
    157 The second line triggers a :exc:`NameError` which is caught by the except
    158 clause. The program will exit, and you will have no idea that this has nothing
    159 to do with the readability of ``"file"``.
    160 
    161 The example above is better written ::
     158The second line triggers a :exc:`NameError`, which is caught by the except
     159clause. The program will exit, and the error message the program prints will
     160make you think the problem is the readability of ``"file"`` when in fact
     161the real error has nothing to do with ``"file"``.
     162
     163A better way to write the above is ::
    162164
    163165   try:
    164        foo = opne("file") # will be changed to "open" as soon as we run it
     166       foo = opne("file")
    165167   except IOError:
    166168       sys.exit("could not open file")
    167169
    168 There are some situations in which the ``except:`` clause is useful: for
    169 example, in a framework when running callbacks, it is good not to let any
    170 callback disturb the framework.
     170When this is run, Python will produce a traceback showing the :exc:`NameError`,
     171and it will be immediately apparent what needs to be fixed.
     172
     173.. index:: bare except, except; bare
     174
     175Because ``except:`` catches *all* exceptions, including :exc:`SystemExit`,
     176:exc:`KeyboardInterrupt`, and :exc:`GeneratorExit` (which is not an error and
     177should not normally be caught by user code), using a bare ``except:`` is almost
     178never a good idea.  In situations where you need to catch all "normal" errors,
     179such as in a framework that runs callbacks, you can catch the base class for
     180all normal exceptions, :exc:`Exception`.  Unfortunately in Python 2.x it is
     181possible for third-party code to raise exceptions that do not inherit from
     182:exc:`Exception`, so in Python 2.x there are some cases where you may have to
     183use a bare ``except:`` and manually re-raise the exceptions you don't want
     184to catch.
    171185
    172186
     
    186200       return open(file).readline()
    187201
    188 Consider the case the file gets deleted between the time the call to
    189 :func:`os.path.exists` is made and the time :func:`open` is called. That means
    190 the last line will throw an :exc:`IOError`. The same would happen if *file*
    191 exists but has no read permission. Since testing this on a normal machine on
    192 existing and non-existing files make it seem bugless, that means in testing the
    193 results will seem fine, and the code will get shipped. Then an unhandled
    194 :exc:`IOError` escapes to the user, who has to watch the ugly traceback.
    195 
    196 Here is a better way to do it. ::
     202Consider the case where the file gets deleted between the time the call to
     203:func:`os.path.exists` is made and the time :func:`open` is called. In that
     204case the last line will raise an :exc:`IOError`.  The same thing would happen
     205if *file* exists but has no read permission.  Since testing this on a normal
     206machine on existent and non-existent files makes it seem bugless, the test
     207results will seem fine, and the code will get shipped.  Later an unhandled
     208:exc:`IOError` (or perhaps some other :exc:`EnvironmentError`) escapes to the
     209user, who gets to watch the ugly traceback.
     210
     211Here is a somewhat better way to do it. ::
    197212
    198213   def get_status(file):
    199214       try:
    200215           return open(file).readline()
    201        except (IOError, OSError):
    202            print "file not found"
     216       except EnvironmentError as err:
     217           print "Unable to open file: {}".format(err)
    203218           sys.exit(1)
    204219
    205 In this version, \*either\* the file gets opened and the line is read (so it
    206 works even on flaky NFS or SMB connections), or the message is printed and the
    207 application aborted.
    208 
    209 Still, :func:`get_status` makes too many assumptions --- that it will only be
    210 used in a short running script, and not, say, in a long running server. Sure,
    211 the caller could do something like ::
     220In this version, *either* the file gets opened and the line is read (so it
     221works even on flaky NFS or SMB connections), or an error message is printed
     222that provides all the available information on why the open failed, and the
     223application is aborted.
     224
     225However, even this version of :func:`get_status` makes too many assumptions ---
     226that it will only be used in a short running script, and not, say, in a long
     227running server. Sure, the caller could do something like ::
    212228
    213229   try:
     
    216232       status = None
    217233
    218 So, try to make as few ``except`` clauses in your code --- those will usually be
    219 a catch-all in the :func:`main`, or inside calls which should always succeed.
    220 
    221 So, the best version is probably ::
     234But there is a better way.  You should try to use as few ``except`` clauses in
     235your code as you can --- the ones you do use will usually be inside calls which
     236should always succeed, or a catch-all in a main function.
     237
     238So, an even better version of :func:`get_status()` is probably ::
    222239
    223240   def get_status(file):
    224241       return open(file).readline()
    225242
    226 The caller can deal with the exception if it wants (for example, if it  tries
     243The caller can deal with the exception if it wants (for example, if it tries
    227244several files in a loop), or just let the exception filter upwards to *its*
    228245caller.
    229246
    230 The last version is not very good either --- due to implementation details, the
    231 file would not be closed when an exception is raised until the handler finishes,
    232 and perhaps not at all in non-C implementations (e.g., Jython). ::
     247But the last version still has a serious problem --- due to implementation
     248details in CPython, the file would not be closed when an exception is raised
     249until the exception handler finishes; and, worse, in other implementations
     250(e.g., Jython) it might not be closed at all regardless of whether or not
     251an exception is raised.
     252
     253The best version of this function uses the ``open()`` call as a context
     254manager, which will ensure that the file gets closed as soon as the
     255function returns::
    233256
    234257   def get_status(file):
    235        fp = open(file)
    236        try:
     258       with open(file) as fp:
    237259           return fp.readline()
    238        finally:
    239            fp.close()
    240260
    241261
     
    262282:func:`splitext`.
    263283
    264 There are also many useful built-in functions people seem not to be aware of for
    265 some reason: :func:`min` and :func:`max` can find the minimum/maximum of any
    266 sequence with comparable semantics, for example, yet many people write their own
    267 :func:`max`/:func:`min`. Another highly useful function is :func:`reduce`. A
    268 classical use of :func:`reduce` is something like ::
    269 
    270    import sys, operator
    271    nums = map(float, sys.argv[1:])
    272    print reduce(operator.add, nums)/len(nums)
    273 
    274 This cute little script prints the average of all numbers given on the command
    275 line. The :func:`reduce` adds up all the numbers, and the rest is just some
    276 pre- and postprocessing.
    277 
    278 On the same note, note that :func:`float`, :func:`int` and :func:`long` all
    279 accept arguments of type string, and so are suited to parsing --- assuming you
    280 are ready to deal with the :exc:`ValueError` they raise.
     284There are also many useful built-in functions people seem not to be aware of
     285for some reason: :func:`min` and :func:`max` can find the minimum/maximum of
     286any sequence with comparable semantics, for example, yet many people write
     287their own :func:`max`/:func:`min`. Another highly useful function is
     288:func:`reduce` which can be used to repeatly apply a binary operation to a
     289sequence, reducing it to a single value.  For example, compute a factorial
     290with a series of multiply operations::
     291
     292   >>> n = 4
     293   >>> import operator
     294   >>> reduce(operator.mul, range(1, n+1))
     295   24
     296
     297When it comes to parsing numbers, note that :func:`float`, :func:`int` and
     298:func:`long` all accept string arguments and will reject ill-formed strings
     299by raising an :exc:`ValueError`.
    281300
    282301
Note: See TracChangeset for help on using the changeset viewer.