0
Effective Python Programming – OSCON 2005




Effective Python Programming
Effective Python Programming – OSCON 2005




        Effective Programming
    Get the job done
●



    Better, more mai...
Effective Python Programming – OSCON 2005




                     Laziness
    In development, laziness can be good
●



...
Effective Python Programming – OSCON 2005




         Effective != Efficient
    Effective does not necessarily mean
●


...
Effective Python Programming – OSCON 2005




                       Target
    Python 2.4
●



    CPython
●
Effective Python Programming – OSCON 2005




        Python Fundamentals
    Learning by tinkering
●



    Everything's ...
Effective Python Programming – OSCON 2005




Short Attention Span Theatre
    Key things to remember
●



    Even if you...
Effective Python Programming – OSCON 2005




              S.A.S. Theatre
    Rule #1: Dictionaries
●



    Rule #2: See...
Effective Python Programming – OSCON 2005




Programming with the hood up
    Introspection
●



    Experimentation
●
Effective Python Programming – OSCON 2005




        Interactive Python
bonanza% python
Python 2.4.1 (#2, Mar 30 2005, 21...
Effective Python Programming – OSCON 2005




                help and dir
    help(obj) – formats docstrings
●



    dir...
Effective Python Programming – OSCON 2005




                        help
>>> import os
>>> help(os.popen)
Help on built-...
Effective Python Programming – OSCON 2005




                       help...
>>> help(8)
Help on int object:


class int(o...
Effective Python Programming – OSCON 2005




                          dir

>>> import popen2
>>> dir(popen2)
['MAXFD', '...
Effective Python Programming – OSCON 2005




       Everything is an object
    ints, strings, files
●



    functions, ...
Effective Python Programming – OSCON 2005




           Objects vs Names
    Variables are references
●



    Just a nam...
Effective Python Programming – OSCON 2005




               Namespaces...
    Namespaces are dictionaries!
●


    >>> im...
Effective Python Programming – OSCON 2005




    Namespace lookup – Classic
    locals
●



    module globals
●



    b...
Effective Python Programming – OSCON 2005




                 Assignment
    Assignment goes to local namespace
●



    ...
Effective Python Programming – OSCON 2005




                        global
    global only for assignment
●



    not n...
Effective Python Programming – OSCON 2005




Namespaces – nested scopes
    statically nested scopes
●


      (nested fu...
Effective Python Programming – OSCON 2005




                         EAFP
    Easier to Ask Forgiveness than
●


    Per...
Effective Python Programming – OSCON 2005




                    Permission...
    Permission:
●


    if hasattr(obj, 'v...
Effective Python Programming – OSCON 2005




                         EAFP
    Exceptions are expensive
●



    Checks c...
Effective Python Programming – OSCON 2005




              Python Typing
    Weak vs Strong
●



    Static vs Dynamic
●
...
Effective Python Programming – OSCON 2005




                 Duck-Typing
    Walks like a duck
●



    ... quacks like ...
Effective Python Programming – OSCON 2005




                 Duck-Typing
    File-like objects
●



    Might only need ...
Effective Python Programming – OSCON 2005




     Duck-Typing – File objects
    def getData(obj):
        data = obj.rea...
Effective Python Programming – OSCON 2005




          More Duck-Typing
    The mapping interface (dictionary)
●



    S...
Effective Python Programming – OSCON 2005




                   Interfaces
    zope.interface
●



    PyProtocols
●



 ...
Effective Python Programming – OSCON 2005




Structured Programming
Effective Python Programming – OSCON 2005




                    Control Flow
    Iterators
●



    Generators
●



    ...
Effective Python Programming – OSCON 2005




               S.A.S. Theatre!
    enumerate
●


    for n in range(len(sequ...
Effective Python Programming – OSCON 2005




            Basic control flow
    while
●



    for
●



    try/except
●
Effective Python Programming – OSCON 2005




                     Iterators
    Returns the next item each time
●



    ...
Effective Python Programming – OSCON 2005




            Files are iterators
    Returns a line
●


    >>> for line in o...
Effective Python Programming – OSCON 2005




            Creating iterators
    iter() built-in
●



    turns a sequence...
Effective Python Programming – OSCON 2005




        More flexible for loops
    Call .next() to get the next item
●




...
Effective Python Programming – OSCON 2005




            Token streams
tokens=['text:hello','style:bold','text:world',
  ...
Effective Python Programming – OSCON 2005




               Push Iterator
    Sometimes you want to check the next
●


  ...
Effective Python Programming – OSCON 2005




                Push Iterator
class PushIterator:
    def __init__(self, ite...
Effective Python Programming – OSCON 2005




               Peek Iterator
    Sibling to PushIterator
●



    Peek at th...
Effective Python Programming – OSCON 2005




                     itertools
    high performance iterator manipulation
●
...
Effective Python Programming – OSCON 2005




                  Generators
    “Good artists copy, great artists steal”
●
...
Effective Python Programming – OSCON 2005




                  Generators
    'yield' passes a result to the caller
●



...
Effective Python Programming – OSCON 2005




                  Generators
>>> def squares(start=1):
...      while True:
...
Effective Python Programming – OSCON 2005




                  Generators
    finish when they fall off the end
●



    ...
Effective Python Programming – OSCON 2005




  Multiple Generator Calls
>>> s1 = squares(5)
>>> s2 = squares(15)
>>> prin...
Effective Python Programming – OSCON 2005




          Generator Example
    DB-API
●



    cursor.fetchone() - get one ...
Effective Python Programming – OSCON 2005



        Possible Solutions
for row in cursor.fetchall():
    processResult(ro...
Effective Python Programming – OSCON 2005




            Generator Version
    def ResultIter(cursor, arraysize=1000):
  ...
Effective Python Programming – OSCON 2005




                      for/else
    for statements can have an else: clause
●...
Effective Python Programming – OSCON 2005




         for/else example

for element in sequence:
    if elementMatched(el...
Effective Python Programming – OSCON 2005




                         try/finally
    finally: clause is always executed
...
Effective Python Programming – OSCON 2005




                    try/finally
    Great for preventing those nightmare
●

...
Effective Python Programming – OSCON 2005




             try/except/else
    try/except can have an else: statement
●


...
Effective Python Programming – OSCON 2005




                  try/except/else
    Put only the important bits in the try...
Effective Python Programming – OSCON 2005




minimising code in a try: block
    This code has a problem:
●


    try:
  ...
Effective Python Programming – OSCON 2005




             switch statement
    python has no switch/case
●



    if/elif...
Effective Python Programming – OSCON 2005

               Dispatch via dict
    if indata == 'FOZZIE':
        showFozzie(...
Effective Python Programming – OSCON 2005




Object Oriented Programming
Effective Python Programming – OSCON 2005




    Using Classes Pythonically
    New-style vs Old-style
●



    More Duck...
Effective Python Programming – OSCON 2005




              S.A.S. Theatre
    __del__ is not your friend
●
Effective Python Programming – OSCON 2005




__del__ often considered harmful
     C++/Java-ism
 ●



     __del__ breaks...
Effective Python Programming – OSCON 2005




        New-style vs Old-style
    Python has two types of class
●



    Ol...
Effective Python Programming – OSCON 2005




         New-style vs Old-style
    New style derive from 'object'
●



    ...
Effective Python Programming – OSCON 2005




       Use New Style Classes
    Most new code should use them
●



    Will...
Effective Python Programming – OSCON 2005




                More Ducks!
    Objects supporting the mapping
●


    inter...
Effective Python Programming – OSCON 2005




            Sometimes you care
    There are times when you care what
●


  ...
Effective Python Programming – OSCON 2005




                     Interfaces
    Documentation
●



    Assertions
●


  ...
Effective Python Programming – OSCON 2005




        Interface Example
class IAudio(Interface):
    '''Lowlevel interface...
Effective Python Programming – OSCON 2005




        Using an Interface
class ALSAAudio(object):
    implements(IAudio)
 ...
Effective Python Programming – OSCON 2005




       Interfaces are dynamic
    Interfaces can be changed at runtime
●



...
Effective Python Programming – OSCON 2005




                     isinstance
    Checking obj.__class__ is evil
●



    ...
Effective Python Programming – OSCON 2005




          inheritance, mixins
    Multiple inheritance is useful
●



    Mi...
Effective Python Programming – OSCON 2005




                 Inheritance
    “Flat is better than nested”
●



    Exces...
Effective Python Programming – OSCON 2005




        Design for subclassing
    Use self.__class__ instead of hardcoded
●...
Effective Python Programming – OSCON 2005




          Base class methods
    Call base class methods from
●


    subcla...
Effective Python Programming – OSCON 2005




Don't Assume You Know Best
    You don't know how people will need to
●


  ...
Effective Python Programming – OSCON 2005




                access control
    Another C++/Java-ism
●


      friend, pu...
Effective Python Programming – OSCON 2005




            __private names
    leading double underscore mangles
●


    na...
Effective Python Programming – OSCON 2005




        Simplifying your APIs
    Damien Conway's “Sufficiently
●


    Adva...
Effective Python Programming – OSCON 2005




             Container object
    Get the objects in a container
●



    Fi...
Effective Python Programming – OSCON 2005




           Container example
    Using the iterator protocol
●


    class C...
Effective Python Programming – OSCON 2005




        __special__ methods
    Used to implement operators
●



    Example...
Effective Python Programming – OSCON 2005




    special methods, examples
    A+B
●


     First tries A.__add__(B)
    ...
Effective Python Programming – OSCON 2005




        Make the API Intuitive
    Every new method name is something
●


  ...
Effective Python Programming – OSCON 2005




                 C++-style cout
    A bit too magical to be recommended:
●

...
Effective Python Programming – OSCON 2005




Demonstrating special methods
  class chatty:
      def __init__(self, name)...
Effective Python Programming – OSCON 2005




         demonstration...
>>> A = chatty('A')
>>> B = chatty('B')
>>> A + B
...
Effective Python Programming – OSCON 2005




        __getattr__ warning
    Special-case __special__ names
●



    Pain...
Effective Python Programming – OSCON 2005




             Get/Set methods
    instead of:
●


    print someobject.getVal...
Effective Python Programming – OSCON 2005




             Get/Set methods
    Sometimes, attributes need to be
●


    co...
Effective Python Programming – OSCON 2005




                     Properties
    Property takes 1-4 arguments:
●


    at...
Effective Python Programming – OSCON 2005




                 Descriptors
    property returns an object called a
●


   ...
Effective Python Programming – OSCON 2005




               staticmethod
    Very limited use
●



    Nearly always bett...
Effective Python Programming – OSCON 2005




                  classmethod
    Alternate constructors
●


    class TimeS...
Effective Python Programming – OSCON 2005




              @classmethod !?
    Decorators
●



    Replaces this:
●


   ...
Effective Python Programming – OSCON 2005




                  Decorators
    Decorators are passed the function
●


    ...
Effective Python Programming – OSCON 2005




                      Laziness
    Python makes things easy
●



    But onl...
Effective Python Programming – OSCON 2005




               S.A.S. Theatre
    dict.setdefault(key, defaultval)
●



    ...
Effective Python Programming – OSCON 2005




                     setdefault
    Turns this:
●


    if key in dictobj:
 ...
Effective Python Programming – OSCON 2005




         Sequence Unpacking
    Most things Just Work:
●


    a, b, c = thr...
Effective Python Programming – OSCON 2005




      Stamping License Plates
    Any time you find yourself writing the
●

...
Effective Python Programming – OSCON 2005




    Boring repetitive code
class Monkey:
  def displayNameAsHTML(self):
    ...
Effective Python Programming – OSCON 2005




       Templated Monkey
def _displayer(what):
    def template(self):
      ...
Effective Python Programming – OSCON 2005




  Making Templates saner
def _displayer(what):
    def template(self, what=w...
Effective Python Programming – OSCON 2005




      Universal Newline Mode
    Windows, Mac, Unix have different line
●


...
Effective Python Programming – OSCON 2005




                codecs.open
    codecs.open provides a file-like object
●


...
Effective Python Programming – OSCON 2005




            Plan for Unicode
    Much easier if you start out allowing
●


 ...
Effective Python Programming – OSCON 2005




                    basestring
    Parent class for str and unicode
●



   ...
Effective Python Programming – OSCON 2005




     The Instant Guide to i18n
    i18n your strings:
●


    from gettext i...
Effective Python Programming – OSCON 2005




          Batteries Included
    Python ships with a large std library
●



...
Effective Python Programming – OSCON 2005




When Things Go Pear-Shaped
    Debugging
●



    Testing
●
Effective Python Programming – OSCON 2005




              S.A.S. Theatre
    The single most useful Python trick I
●


 ...
Effective Python Programming – OSCON 2005




                       unittest
    Python standard unittest module
●



   ...
Effective Python Programming – OSCON 2005




                      doctest
    More Pythonic
●



    Perfect for the laz...
Effective Python Programming – OSCON 2005




              Running Tests
    A good test runner makes it more likely
●


...
Effective Python Programming – OSCON 2005




      Dealing with tracebacks
    Sometimes, the default traceback isn't
●

...
Effective Python Programming – OSCON 2005




                          cgitb
    Debugging CGI scripts can be horrible
●
...
Effective Python Programming – OSCON 2005




Making Life Hard For Yourself
    Things to avoid
●



    Recognising refac...
Effective Python Programming – OSCON 2005




               S.A.S. Theatre
    Bare except: clauses will nearly always
●
...
Effective Python Programming – OSCON 2005




       Consistent Coding Style
    Pick a style, and stick to it
●


      P...
Effective Python Programming – OSCON 2005




       from module import *
    Don't
●



    Figuring out where a name com...
Effective Python Programming – OSCON 2005




              Circular Imports
    Circular imports lead to subtle bugs:
●

...
Effective Python Programming – OSCON 2005




         more on exceptions
    Raising a new exception from an
●


    exce...
Effective Python Programming – OSCON 2005




         Refactoring Targets
    Learn to spot potential problems
●
Effective Python Programming – OSCON 2005




          Long Argument Lists
    Once a function gets past a couple of
●


...
Effective Python Programming – OSCON 2005




               Format Strings
    Similar problem with format strings
●


  ...
Effective Python Programming – OSCON 2005




              string.Template
    Even simpler
●


    >>> from string impor...
Effective Python Programming – OSCON 2005




                $ == Perl!?!
    The $ sign is only accepted in the
●


    ...
Effective Python Programming – OSCON 2005




            key in sequence
    Any time you use 'in', check the RHS
●



  ...
Effective Python Programming – OSCON 2005




           Too many globals
    Overuse of 'global' usually indicates
●


  ...
Effective Python Programming – OSCON 2005




    Learning by (bad) example
    Lots of Python code to learn from
●



   ...
Effective Python Programming – OSCON 2005




           map/filter/reduce
    map and filter using a lambda should
●


  ...
Effective Python Programming – OSCON 2005




                 string module
    string methods are better
●


    >>> imp...
Effective Python Programming – OSCON 2005




    backslash line continuations
    Almost never needed
●



    Not needed...
Effective Python Programming – OSCON 2005




                    has_key()
    key in dict
●



    dict.get(key, default...
Effective Python Programming – OSCON 2005




         Circular references
    Not so much of a problem now
●


    (garba...
Effective Python Programming – OSCON 2005




         Regular Expressions
    Should not be the first hammer in your
●


...
Effective Python Programming – OSCON 2005




                 re.compile()
    re.compile() returns a compiled
●


    ex...
Effective Python Programming – OSCON 2005




            named RE groups
    Use named RE groups rather than
●


    numb...
Effective Python Programming – OSCON 2005




    Defensive RE programming
    Check the string matches what you
●


    e...
Effective Python Programming – OSCON 2005




Efficient Python Programming
    Making Python Go Fast
●
Effective Python Programming – OSCON 2005




              S.A.S. Theatre
    function calls are slow
●
Effective Python Programming – OSCON 2005




Making your Python code fast
    dicts, list.sort() are highly tuned
●



  ...
Effective Python Programming – OSCON 2005




              profile/hotshot
    Figure out where the slow bits are
●



  ...
Effective Python Programming – OSCON 2005




          numeric/numarray
    Insanely optimised array operations
●



    ...
Effective Python Programming – OSCON 2005




                        Pyrex
    Python dialect that's compiled to C
●



 ...
Effective Python Programming – OSCON 2005




                  __slots__
    Optimisation trick
●



    Python objects s...
Effective Python Programming – OSCON 2005




                  __slots__
    Don't use __slots__ as some sort of
●


    ...
Effective Python Programming – OSCON 2005




     Tying it all back together
    Java DOM Node
●



    Good example of a...
Effective Python Programming – OSCON 2005




           Node.getChildNodes()
    Returns the child nodes of the current
●...
Effective Python Programming – OSCON 2005




        getValue()/setValue()
    Instead, just use node.value
●



    Or u...
Effective Python Programming – OSCON 2005




                isSameNode()
    Implement a __eq__ method
●


    thisNode ...
Effective Python Programming – OSCON 2005




    compareDocumentPosition()
    Compares Node's document position to
●


 ...
Effective Python Programming – OSCON 2005




    parent/child reference cycle
    Remember, a parent child reference
●


...
Effective Python Programming – OSCON 2005




               Wrapping Up
    Write Python code in Python
●



    Might in...
Effective Python Programming – OSCON 2005

    Beautiful is better than ugly.
●


    Explicit is better than implicit.
●
...
Upcoming SlideShare
Loading in...5
×

effective_r27

3,426

Published on

Published in: Technology, Education
0 Comments
13 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,426
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
136
Comments
0
Likes
13
Embeds 0
No embeds

No notes for slide

Transcript of "effective_r27"

  1. 1. Effective Python Programming – OSCON 2005 Effective Python Programming
  2. 2. Effective Python Programming – OSCON 2005 Effective Programming Get the job done ● Better, more maintainable code ● Use the language's strengths ● Python is not: ● C++ Java Perl ...
  3. 3. Effective Python Programming – OSCON 2005 Laziness In development, laziness can be good ● Do things right the first time ● Don't re-invent every wheel ● Death to NIH ●
  4. 4. Effective Python Programming – OSCON 2005 Effective != Efficient Effective does not necessarily mean ● efficient Optimise for development time ● Then worry about performance ● We'll touch on efficient code, later ●
  5. 5. Effective Python Programming – OSCON 2005 Target Python 2.4 ● CPython ●
  6. 6. Effective Python Programming – OSCON 2005 Python Fundamentals Learning by tinkering ● Everything's an object ● Namespaces ● EAFP ● Duck Typing ●
  7. 7. Effective Python Programming – OSCON 2005 Short Attention Span Theatre Key things to remember ● Even if you sleep through the rest, ● you'll still get something
  8. 8. Effective Python Programming – OSCON 2005 S.A.S. Theatre Rule #1: Dictionaries ● Rule #2: See Rule #1 ●
  9. 9. Effective Python Programming – OSCON 2005 Programming with the hood up Introspection ● Experimentation ●
  10. 10. Effective Python Programming – OSCON 2005 Interactive Python bonanza% python Python 2.4.1 (#2, Mar 30 2005, 21:51:10) [GCC 3.3.5 (Debian 1:3.3.5-8ubuntu2)] on linux2 Type quot;helpquot;, quot;copyrightquot;, quot;creditsquot; or quot;licensequot; ... >>>
  11. 11. Effective Python Programming – OSCON 2005 help and dir help(obj) – formats docstrings ● dir(obj) – shows attributes ●
  12. 12. Effective Python Programming – OSCON 2005 help >>> import os >>> help(os.popen) Help on built-in function popen in module posix: popen(...) popen(command [, mode='r' [, bufsize]]) -> pipe Open a pipe to/from a command returning a file object.
  13. 13. Effective Python Programming – OSCON 2005 help... >>> help(8) Help on int object: class int(object) | int(x[, base]) -> integer | | Convert a string or number to an integer, if | possible. A floating point argument will be | truncated towards zero (this does not include a | string representation of a floating point | number!) When converting a string, use | the optional base. It is an error to supply a
  14. 14. Effective Python Programming – OSCON 2005 dir >>> import popen2 >>> dir(popen2) ['MAXFD', 'Popen3', 'Popen4', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '_active', '_cleanup', '_test', 'os', 'popen2', 'popen3', 'popen4', 'sys']
  15. 15. Effective Python Programming – OSCON 2005 Everything is an object ints, strings, files ● functions, modules, classes ● Variables are just labels ●
  16. 16. Effective Python Programming – OSCON 2005 Objects vs Names Variables are references ● Just a name referring to an object ● Stored in a namespace ● (defaults to the local namespace)
  17. 17. Effective Python Programming – OSCON 2005 Namespaces... Namespaces are dictionaries! ● >>> import sys >>> def foo(a=1, b=2): ... c = quot;helloquot; ... print sys._getframe().f_locals ... >>> >>> foo(a=4) {'a': 4, 'c': 'hello', 'b': 2}
  18. 18. Effective Python Programming – OSCON 2005 Namespace lookup – Classic locals ● module globals ● built-ins ●
  19. 19. Effective Python Programming – OSCON 2005 Assignment Assignment goes to local namespace ● Unless 'global' statement ●
  20. 20. Effective Python Programming – OSCON 2005 global global only for assignment ● not needed for getting a value ● globals are slower! ●
  21. 21. Effective Python Programming – OSCON 2005 Namespaces – nested scopes statically nested scopes ● (nested function definitions) useful for lambda: ● def createUpdater(self): return lambda foo, bar: self.update(foo,bar) nested function calls ● example later of this
  22. 22. Effective Python Programming – OSCON 2005 EAFP Easier to Ask Forgiveness than ● Permission Very basic Python concept ●
  23. 23. Effective Python Programming – OSCON 2005 Permission... Permission: ● if hasattr(obj, 'value'): value = obj.value else: value = None Forgiveness: ● try: read = obj.value except AttributeError: value = None
  24. 24. Effective Python Programming – OSCON 2005 EAFP Exceptions are expensive ● Checks can also be expensive ● Case-by-case – how often is it expected ● to fail?
  25. 25. Effective Python Programming – OSCON 2005 Python Typing Weak vs Strong ● Static vs Dynamic ● C++/Java: strong static typing ● Python: strong dynamic typing ●
  26. 26. Effective Python Programming – OSCON 2005 Duck-Typing Walks like a duck ● ... quacks like a duck ● ... it's a duck ●
  27. 27. Effective Python Programming – OSCON 2005 Duck-Typing File-like objects ● Might only need 'read()' ●
  28. 28. Effective Python Programming – OSCON 2005 Duck-Typing – File objects def getData(obj): data = obj.read() print data f = open('file.txt') getData(f) Actually, that data file was gzipped: ● import gzip f = gzip.GzipFile('file.txt.gz') getData(f)
  29. 29. Effective Python Programming – OSCON 2005 More Duck-Typing The mapping interface (dictionary) ● Start with a dictionary ● Slot in a different implementation ● e.g. network, database, ... ●
  30. 30. Effective Python Programming – OSCON 2005 Interfaces zope.interface ● PyProtocols ● Assert that an object implements an ● interface Documentation ● Adaptation ● Future Python ●
  31. 31. Effective Python Programming – OSCON 2005 Structured Programming
  32. 32. Effective Python Programming – OSCON 2005 Control Flow Iterators ● Generators ● for/else ● try/finally ● try/except/else ● switch statement ●
  33. 33. Effective Python Programming – OSCON 2005 S.A.S. Theatre! enumerate ● for n in range(len(sequence)): element = sequence[n] instead: ● for n, element in enumerate(sequence): enumerate returns an iterator ● >>> print enumerate([]) <enumerate object at 0xb7df418c>
  34. 34. Effective Python Programming – OSCON 2005 Basic control flow while ● for ● try/except ●
  35. 35. Effective Python Programming – OSCON 2005 Iterators Returns the next item each time ● No need to have all items in memory ● More flexible ●
  36. 36. Effective Python Programming – OSCON 2005 Files are iterators Returns a line ● >>> for line in open('/etc/resolv.conf'): ... print quot;got line '%s'quot;%(line.strip()) ... got line 'nameserver 210.15.254.240' got line 'nameserver 210.15.254.241' got line 'nameserver 203.10.110.101' got line 'nameserver 203.17.103.1'
  37. 37. Effective Python Programming – OSCON 2005 Creating iterators iter() built-in ● turns a sequence into an iterator ● classes can have an __iter__ method ● that returns an iterator
  38. 38. Effective Python Programming – OSCON 2005 More flexible for loops Call .next() to get the next item ● iterobj = iter(sequence) for item in iterobj: if item == 'extended': item = item + iterobj.next()
  39. 39. Effective Python Programming – OSCON 2005 Token streams tokens=['text:hello','style:bold','text:world', 'text:goodbye','style:italic','text:world'] tokens = iter(tokens) for tok in tokens: what,value = tok.split(':',1) if what == 'text': handlePlainToken(value) elif what == 'style': what, value = tok.next().split(':', 1) if style == 'bold': handleBoldToken(value) elif style == 'italic': handleItalicToken(value)
  40. 40. Effective Python Programming – OSCON 2005 Push Iterator Sometimes you want to check the next ● item, but not always consume it Push it back onto the iterator! ● Like stdio's getc()/ungetc() ●
  41. 41. Effective Python Programming – OSCON 2005 Push Iterator class PushIterator: def __init__(self, iter): self.iter = iter self.pushed = [] def push(self, value): self.pushed.append(value) def next(self): if self.pushed: return self.pushed.pop() else: return self.iter.next() def __iter__(self): return self
  42. 42. Effective Python Programming – OSCON 2005 Peek Iterator Sibling to PushIterator ● Peek at the next result (without ● consuming it)
  43. 43. Effective Python Programming – OSCON 2005 itertools high performance iterator manipulation ● functional programming ●
  44. 44. Effective Python Programming – OSCON 2005 Generators “Good artists copy, great artists steal” ● - Picasso Stolen from Icon ● functions containing 'yield' are a ● generator When called, returns a generator object ● ... which is an iterator ●
  45. 45. Effective Python Programming – OSCON 2005 Generators 'yield' passes a result to the caller ● execution is suspended ● when next() is called again, resumes ● where it left off
  46. 46. Effective Python Programming – OSCON 2005 Generators >>> def squares(start=1): ... while True: ... yield start * start ... start += 1 ... >>> sq = squares(4) >>> sq <generator object at 0xb7df440c> >>> sq.next() 16 >>> sq.next() 25
  47. 47. Effective Python Programming – OSCON 2005 Generators finish when they fall off the end ● or 'return' ● Generators can't 'return' a value ● Generators can be called multiple times ●
  48. 48. Effective Python Programming – OSCON 2005 Multiple Generator Calls >>> s1 = squares(5) >>> s2 = squares(15) >>> print s1.next(), s2.next(), s1.next(), s2.next() 25 225 36 256
  49. 49. Effective Python Programming – OSCON 2005 Generator Example DB-API ● cursor.fetchone() - get one row ● Inefficient! cursor.fetchall() - get all rows ● Could consume a lot of memory cursor.fetchmany(N) – get N rows ● Slightly fiddly
  50. 50. Effective Python Programming – OSCON 2005 Possible Solutions for row in cursor.fetchall(): processResult(row) row = cursor.fetchone() while row: processResult(row) row = cursor.fetchone() while True: rows = cursor.fetchmany(100) if not rows: break for row in rows: processResult(row)
  51. 51. Effective Python Programming – OSCON 2005 Generator Version def ResultIter(cursor, arraysize=1000): while True: results = cursor.fetchmany(arraysize) if not results: break for result in results: yield result Using this: ● for res in ResultIter(cursor): processRow(res)
  52. 52. Effective Python Programming – OSCON 2005 for/else for statements can have an else: clause ● executed when the for loop exhausts ● it's loop (no 'break', return or exception)
  53. 53. Effective Python Programming – OSCON 2005 for/else example for element in sequence: if elementMatched(element): correct = element break else: print quot;no elements matchedquot; correct = None
  54. 54. Effective Python Programming – OSCON 2005 try/finally finally: clause is always executed ● resource cleanup ● lock = acquireLock() try: val = doSomeStuff() if val is None: raise ValueError('got None') elif val < 0: return finally: lock.release()
  55. 55. Effective Python Programming – OSCON 2005 try/finally Great for preventing those nightmare ● bugs “This should never happen” ● Chances are it will ● Program Defensively ● The Universe Hates You. Woefully underused ●
  56. 56. Effective Python Programming – OSCON 2005 try/except/else try/except can have an else: statement ● executed when no exception occurred ●
  57. 57. Effective Python Programming – OSCON 2005 try/except/else Put only the important bits in the try: ● block try: import gtk except: MyWindow = None else: MyWindow = gtk.Window()
  58. 58. Effective Python Programming – OSCON 2005 minimising code in a try: block This code has a problem: ● try: data = obj.read() except AttributeError: data = '' This masks any AttributeErrors in the ● read() method Source of hard-to-find bugs ●
  59. 59. Effective Python Programming – OSCON 2005 switch statement python has no switch/case ● if/elif/elif/elif/else ● use a dictionary ●
  60. 60. Effective Python Programming – OSCON 2005 Dispatch via dict if indata == 'FOZZIE': showFozzie() elif indata == 'KERMIT': showKermit() ... else: showUnknownMuppet() becomes: ● callDict = { 'FOZZIE': showFozzie, 'KERMIT': showKermit, ... } func = callDict.get(indata, showUnknownMuppet) func()
  61. 61. Effective Python Programming – OSCON 2005 Object Oriented Programming
  62. 62. Effective Python Programming – OSCON 2005 Using Classes Pythonically New-style vs Old-style ● More Ducks! ● isinstance ● inheritance, mixins ● access control ● Simplifying your APIs ●
  63. 63. Effective Python Programming – OSCON 2005 S.A.S. Theatre __del__ is not your friend ●
  64. 64. Effective Python Programming – OSCON 2005 __del__ often considered harmful C++/Java-ism ● __del__ breaks garbage collector ● non-deterministic ● doesn't always get called usefully when ● Python is exiting use a weakref in some cases ●
  65. 65. Effective Python Programming – OSCON 2005 New-style vs Old-style Python has two types of class ● Old-style classes are the original ones ● New-style (in 2.2) fix issues with these ● Difference between C types and Python classes Can inherit from built-in types (e.g. dict) Some shiny new features
  66. 66. Effective Python Programming – OSCON 2005 New-style vs Old-style New style derive from 'object' ● New style classes in 2.2 ● Fix for implementation issues in original ● classes Many new features ● properties descriptors __new__ .....
  67. 67. Effective Python Programming – OSCON 2005 Use New Style Classes Most new code should use them ● Will become the default in Python 3.0 ●
  68. 68. Effective Python Programming – OSCON 2005 More Ducks! Objects supporting the mapping ● interface: dictionaries *dbm database files shelves db_row instances
  69. 69. Effective Python Programming – OSCON 2005 Sometimes you care There are times when you care what ● things are passed Check for the methods you need ● if hasattr(obj, 'read'): obj.read() else: raise ValueError Or use an Interface ●
  70. 70. Effective Python Programming – OSCON 2005 Interfaces Documentation ● Assertions ● def getAudioFromSource(obj): if not IAudio(obj): raise ValueError('expected audio, got %r'% obj) return audio.read() Adaptation ● Automatically adapt an IFoo to an IBar
  71. 71. Effective Python Programming – OSCON 2005 Interface Example class IAudio(Interface): '''Lowlevel interface to audio source/sink.''' def close(): '''Close the underlying audio device''' def reopen(): '''Reopen a closed audio device''' def isOpen(): '''Return True if underlying audio open''' def read(): '''Return a packet of audio from device.''' def write(data): '''Write audio to device.'''
  72. 72. Effective Python Programming – OSCON 2005 Using an Interface class ALSAAudio(object): implements(IAudio) def reopen(self): .... def close(self): .... def isOpen(self): .... alsa = ALSAAudio() IAudio.implementedBy(alsa) IAudio(alsa)
  73. 73. Effective Python Programming – OSCON 2005 Interfaces are dynamic Interfaces can be changed at runtime ● Assert that a 3rd party object ● implements an interface Register an adapter from one Interface ● to another
  74. 74. Effective Python Programming – OSCON 2005 isinstance Checking obj.__class__ is evil ● Breaks subclassing ● type(foo) is ancient, and clunky ● Use isinstance: ● if isinstance(num, basestring): num = int(num) if not isinstance(thing, (int, float)): raise ValueError('expected a number')
  75. 75. Effective Python Programming – OSCON 2005 inheritance, mixins Multiple inheritance is useful ● Mixin classes – assemble components ● into a class Select from multiple implementations ●
  76. 76. Effective Python Programming – OSCON 2005 Inheritance “Flat is better than nested” ● Excessive inheritance trees are painful ● Use inheritance when you need it ●
  77. 77. Effective Python Programming – OSCON 2005 Design for subclassing Use self.__class__ instead of hardcoded ● class names class Item: def __init__(self, value): self.value = value def getNextItem(self): newItem = self.__class__() newItem.value = self.value + 1
  78. 78. Effective Python Programming – OSCON 2005 Base class methods Call base class methods from ● subclassed methods! Protects you if parent class changes ● Particularly important for __init__ ● class Monkey(Simian): def __init__(self, bananas=2, *args, **kwargs): self.bananas = bananas Simian.__init__(self, *args, **kwargs)
  79. 79. Effective Python Programming – OSCON 2005 Don't Assume You Know Best You don't know how people will need to ● use your code Think about how someone could extend ● your classes Design classes accordingly ● Document the methods ● Factor out the useful bits ●
  80. 80. Effective Python Programming – OSCON 2005 access control Another C++/Java-ism ● friend, public, private, ... Python: “Everyone's a consenting ● adult” Convention: leading underscore signals ● “implementation detail” Better yet: document the API of the ● class
  81. 81. Effective Python Programming – OSCON 2005 __private names leading double underscore mangles ● names In theory useful to stop people stepping ● on implementation details In practice, annoying ● Personal goal for 2.5 is to remove all use from the stdlib
  82. 82. Effective Python Programming – OSCON 2005 Simplifying your APIs Damien Conway's “Sufficiently ● Advanced Magic” But not quite that advanced... ●
  83. 83. Effective Python Programming – OSCON 2005 Container object Get the objects in a container ● First attempt: ● for child in container.getChildren(): doSomethingWithObject(child) Unnecessary API ● Python already has a good way to spell ● this: for child in container: doSomethingWithObject(child)
  84. 84. Effective Python Programming – OSCON 2005 Container example Using the iterator protocol ● class Container(object): def __init__(self, *children): self.children = children def __iter__(self): return iter(self.children) cont = Container(1,2,3,4,5) for c in cont: print c
  85. 85. Effective Python Programming – OSCON 2005 __special__ methods Used to implement operators ● Examples: ● __str__ - string representation __setitem__ - obj[key] = val ==> obj.__setitem__(key,val) __add__ - add something to this object __getattr__ - get an attribute of this object __eq__ - object is being compared to another
  86. 86. Effective Python Programming – OSCON 2005 special methods, examples A+B ● First tries A.__add__(B) Then B.__radd__(A) (We're ignoring __coerce__) A == B ● In order: A.__eq__(B), B.__eq__(A), A.__cmp__(B), and then B.__cmp__(A)
  87. 87. Effective Python Programming – OSCON 2005 Make the API Intuitive Every new method name is something ● that has to be remembered documented Finite amount of brain space ● Use intuitive operators ● But don't get too clever ●
  88. 88. Effective Python Programming – OSCON 2005 C++-style cout A bit too magical to be recommended: ● class CppFile: def __init__(self, fp): self.fp = fp def __lshift__(self, someobj): self.fp.write(str(someobj)) return self import sys cout = CppFile(sys.stdout) cout << quot;hello” << “worldnquot;
  89. 89. Effective Python Programming – OSCON 2005 Demonstrating special methods class chatty: def __init__(self, name): self.name = name def __getattr__(self, what): print self.name, quot;asked forquot;, what raise AttributeError(what)
  90. 90. Effective Python Programming – OSCON 2005 demonstration... >>> A = chatty('A') >>> B = chatty('B') >>> A + B A asked for __coerce__ A asked for __add__ B asked for __coerce__ B asked for __radd__ Traceback (most recent call last): File quot;<stdin>quot;, line 1, in ? TypeError: unsupported operand type(s) for +: 'instance' and 'instance' >>> print A A asked for __str__ A asked for __repr__ <__main__.chatty instance at 0xb7df47cc>
  91. 91. Effective Python Programming – OSCON 2005 __getattr__ warning Special-case __special__ names ● Pain, otherwise ● Python uses lots of special methods ● e.g. __repr__ to print ● def __getattr__(self, name): if name.startswith('__') and name.endswith('__'): raise AttributeError(name) return self.remoteObject.lookupName(name)
  92. 92. Effective Python Programming – OSCON 2005 Get/Set methods instead of: ● print someobject.getValue() someobject.setValue(5) use: ● print someobject.value someobject.value = 5
  93. 93. Effective Python Programming – OSCON 2005 Get/Set methods Sometimes, attributes need to be ● computed Use a property! ● class Magic: def _getMagicNum(self): return findTheMagicNumber() def _setMagicNum(self, value) setTheMagicNumber(value) magicNumber = property(_getMagicNum, _setMagicNum)
  94. 94. Effective Python Programming – OSCON 2005 Properties Property takes 1-4 arguments: ● attribute = property(getmeth, setmeth, delmeth, doc='') set method and del method optional ● doc sets a docstring – use it ● monkeyCount = property(getMonkeys, doc='The count of monkeys in this barrel') Only use property when needed ● Attributes are a lot faster
  95. 95. Effective Python Programming – OSCON 2005 Descriptors property returns an object called a ● descriptor extremely powerful, but you'll have to ● read up on them yourself descriptors are how 'self' gets inserted ● as the first argument of a method classmethod and staticmethod are also ● descriptors
  96. 96. Effective Python Programming – OSCON 2005 staticmethod Very limited use ● Nearly always better to use a function ●
  97. 97. Effective Python Programming – OSCON 2005 classmethod Alternate constructors ● class TimeStamp(object): def __init__(self, h, m, s): self.h, self.m, self.s = h, m, s @classmethod def fromString(cls, string): h,m,s = [int(x) for x in string.split(':')] return cls(h, m, s) Alternate constructors make nicer API ● Not many other uses ●
  98. 98. Effective Python Programming – OSCON 2005 @classmethod !? Decorators ● Replaces this: ● def alternateCtor(cls, argumentList): ... alternateCtor = classmethod(alternateCtor) With this: ● @classmethod def alternateCtor(cls, argumentList): ...
  99. 99. Effective Python Programming – OSCON 2005 Decorators Decorators are passed the function ● object, return a new function object Remember to copy func_name and ● __doc__ if you create a new function object!
  100. 100. Effective Python Programming – OSCON 2005 Laziness Python makes things easy ● But only if you let it ● Anytime you feel like you're doing too ● much, take a step back
  101. 101. Effective Python Programming – OSCON 2005 S.A.S. Theatre dict.setdefault(key, defaultval) ● sets a value (if not already set), returns ● value
  102. 102. Effective Python Programming – OSCON 2005 setdefault Turns this: ● if key in dictobj: dictobj[key].append(val) else: dictobj[key] = [val] Into this: ● dictobj.setdefault(key, []).append(val)
  103. 103. Effective Python Programming – OSCON 2005 Sequence Unpacking Most things Just Work: ● a, b, c = threetuple Swap two values: ● a, b = b, a Get and clear a value: ● val, self.val = self.val, None
  104. 104. Effective Python Programming – OSCON 2005 Stamping License Plates Any time you find yourself writing the ● same/similar code repeatedly, you're working too hard Use a template function (a closure) ●
  105. 105. Effective Python Programming – OSCON 2005 Boring repetitive code class Monkey: def displayNameAsHTML(self): cssClass = self.cssClass html='<div class=”%s”>%s</div>'%(cssClass, self.name) return html def displayBananasAsHTML(self): cssClass = self.cssClass html='<div class=”%s”>%s</div>'%(cssClass, self.bananas) return html
  106. 106. Effective Python Programming – OSCON 2005 Templated Monkey def _displayer(what): def template(self): val = getattr(self, what) cssClass = self.cssClass return '<div class=”%s”>%s</div>'%(cssClass, val) return html return template class Monkey: displayNameAsHTML = _displayer('name') displayBananasAsHTML = _displayer('bananas')
  107. 107. Effective Python Programming – OSCON 2005 Making Templates saner def _displayer(what): def template(self, what=what): ... template.func_name = 'display%sAsHtml'%( what.capitalize()) template.__doc__ = 'Returns %s as HTML'%what return template
  108. 108. Effective Python Programming – OSCON 2005 Universal Newline Mode Windows, Mac, Unix have different line ● endings Annoying ● Open files with 'rU', and it just works ● fp = open('somefile.txt', 'rU')
  109. 109. Effective Python Programming – OSCON 2005 codecs.open codecs.open provides a file-like object ● in a particular encoding useful for reading and writing ● more duck typing ●
  110. 110. Effective Python Programming – OSCON 2005 Plan for Unicode Much easier if you start out allowing ● unicode Even if not, it's not too hard to retrofit ●
  111. 111. Effective Python Programming – OSCON 2005 basestring Parent class for str and unicode ● Useful in isinstance() checks ● >>> isinstance('moose', basestring) True >>> isinstance(u'møøse', basestring) True
  112. 112. Effective Python Programming – OSCON 2005 The Instant Guide to i18n i18n your strings: ● from gettext import gettext as _ _('Enter your name') Decode strings on input: ● bytes = quot;naïvequot; unistr = bytes.decode('iso8859-1') Encode unicode on output: ● print unistr.encode('iso8859-1', 'replace')
  113. 113. Effective Python Programming – OSCON 2005 Batteries Included Python ships with a large std library ● Don't re-invent the wheel ●
  114. 114. Effective Python Programming – OSCON 2005 When Things Go Pear-Shaped Debugging ● Testing ●
  115. 115. Effective Python Programming – OSCON 2005 S.A.S. Theatre The single most useful Python trick I ● know: import pdb; pdb.set_trace() When executed, drops into the Python ● debugger
  116. 116. Effective Python Programming – OSCON 2005 unittest Python standard unittest module ● Port of Junit ● Makes writing tests not-too-horrible ● API is still a bit cumbersome ●
  117. 117. Effective Python Programming – OSCON 2005 doctest More Pythonic ● Perfect for the lazy programmer ● Cut-n-paste from an interactive session ● Doubles as documentation and ● examples
  118. 118. Effective Python Programming – OSCON 2005 Running Tests A good test runner makes it more likely ● people will actually run the tests test.py (in Zope3) ●
  119. 119. Effective Python Programming – OSCON 2005 Dealing with tracebacks Sometimes, the default traceback isn't ● what you want traceback module ● try: .... except: e, v, tb = sys.exc_info() traceback.print_tb(t)
  120. 120. Effective Python Programming – OSCON 2005 cgitb Debugging CGI scripts can be horrible ● import cgitb; cgitb.enable() Displays nicely formatted tracebacks ● context variables arguments Can log in text or html, to the browser ● or files
  121. 121. Effective Python Programming – OSCON 2005 Making Life Hard For Yourself Things to avoid ● Recognising refactoring targets ● Learning from (bad) examples ●
  122. 122. Effective Python Programming – OSCON 2005 S.A.S. Theatre Bare except: clauses will nearly always ● bite you later Silently eating exceptions is bad ● except: should either log the exception, ● or re-raise it Just 'raise' will re-raise the current ● exception
  123. 123. Effective Python Programming – OSCON 2005 Consistent Coding Style Pick a style, and stick to it ● PEP 008 has one, or choose your own Use tools where necessary ● emacs python mode reindent.py Pick a consistent indent style! ●
  124. 124. Effective Python Programming – OSCON 2005 from module import * Don't ● Figuring out where a name comes from ● should not be painful
  125. 125. Effective Python Programming – OSCON 2005 Circular Imports Circular imports lead to subtle bugs: ● Module A: ● import moduleB Module B: ● import moduleA Defer imports until you need them to ● fix this
  126. 126. Effective Python Programming – OSCON 2005 more on exceptions Raising a new exception from an ● except: clause often makes debugging harder The new traceback will point at the ● except: block, not the original exception A bare 'raise' will re-raise the current ● exception
  127. 127. Effective Python Programming – OSCON 2005 Refactoring Targets Learn to spot potential problems ●
  128. 128. Effective Python Programming – OSCON 2005 Long Argument Lists Once a function gets past a couple of ● arguments, either: refactor it or use keyword arguments def someHideousFunction(firstname, surname, addr1, addr2, zipcode, city, state): .... someHideousFunction(firstname=”Anthony”, surname=”Baxter”, ....
  129. 129. Effective Python Programming – OSCON 2005 Format Strings Similar problem with format strings ● using % operator Use the dict form: ● addrInfo = dict(firstname='Anthony', surname='Baxter', ...) label = “””%(firstname)s %(surname)s %(addr1)s %(addr2)s %(city)s, %(state)s %(zipcode)s””” % addrInfo
  130. 130. Effective Python Programming – OSCON 2005 string.Template Even simpler ● >>> from string import Template >>> s = Template('$cheese is from ${country}') >>> print s.substitute(cheese='Gouda', country='the Netherlands') Gouda is from the Netherlands >>> print s.substitute(cheese='Gouda') Traceback (most recent call last): [...] KeyError: 'country' >>> print s.safe_substitute(cheese='Gouda') Gouda is from ${country}
  131. 131. Effective Python Programming – OSCON 2005 $ == Perl!?! The $ sign is only accepted in the ● strings passed to string.Template Lots of other languages use $ - it's the ● obvious choice
  132. 132. Effective Python Programming – OSCON 2005 key in sequence Any time you use 'in', check the RHS ● If a sequence, how big will it get? ● O(N) ● Use a dict, or a set ●
  133. 133. Effective Python Programming – OSCON 2005 Too many globals Overuse of 'global' usually indicates ● poor code Refactor into a class, storing the global ● values as attributes
  134. 134. Effective Python Programming – OSCON 2005 Learning by (bad) example Lots of Python code to learn from ● Some of it is old ● People pick up bad habits from this ●
  135. 135. Effective Python Programming – OSCON 2005 map/filter/reduce map and filter using a lambda should ● be replaced with listcomps or genexprs reduce: just don't use ● sum() replaced 90% of use cases other use cases usually leads to headscratching
  136. 136. Effective Python Programming – OSCON 2005 string module string methods are better ● >>> import string >>> name = 'anthony' >>> print string.upper(name) ANTHONY >>> print name.upper() ANTHONY Remember: strings are immutable, ● methods return a copy
  137. 137. Effective Python Programming – OSCON 2005 backslash line continuations Almost never needed ● Not needed if there's open braces ● So wrap in ( ) ● Works for import, too! (in 2.4) ● from package.subpkg.module import (Aname, Bname, Cname, Dname)
  138. 138. Effective Python Programming – OSCON 2005 has_key() key in dict ● dict.get(key, default) ●
  139. 139. Effective Python Programming – OSCON 2005 Circular references Not so much of a problem now ● (garbage collector) Remember: __del__ stops GC! ●
  140. 140. Effective Python Programming – OSCON 2005 Regular Expressions Should not be the first hammer in your ● toolbox Sometimes, a real parser is better ● If you must use them... ●
  141. 141. Effective Python Programming – OSCON 2005 re.compile() re.compile() returns a compiled ● expression much, much faster than re-compiling ● each time nicer API, too ●
  142. 142. Effective Python Programming – OSCON 2005 named RE groups Use named RE groups rather than ● numbered ones r = re.compile('(?P<name>[^ ]+) (?P<surname>[^ ]+)') match = r.match('Anthony Baxter') match.group('surname')
  143. 143. Effective Python Programming – OSCON 2005 Defensive RE programming Check the string matches what you ● expect, first Debugging complex RE failures is a ● world of hurt
  144. 144. Effective Python Programming – OSCON 2005 Efficient Python Programming Making Python Go Fast ●
  145. 145. Effective Python Programming – OSCON 2005 S.A.S. Theatre function calls are slow ●
  146. 146. Effective Python Programming – OSCON 2005 Making your Python code fast dicts, list.sort() are highly tuned ● globals are slower than locals ● list.pop(0), list.insert(0, value) are slow ● reverse your list, or use collections.deque move fixed code out of the critical path ●
  147. 147. Effective Python Programming – OSCON 2005 profile/hotshot Figure out where the slow bits are ● Get the code right first (with unit tests!) ● and then optimise
  148. 148. Effective Python Programming – OSCON 2005 numeric/numarray Insanely optimised array operations ● If dealing with numbers, use them ●
  149. 149. Effective Python Programming – OSCON 2005 Pyrex Python dialect that's compiled to C ● Start with straight Python code, add ● declarations to use C types Only optimise the hot spots ● Much easier than trying to write ● straight C code extensions
  150. 150. Effective Python Programming – OSCON 2005 __slots__ Optimisation trick ● Python objects store attributes in a ● dictionary __slots__ is a fixed list ● reduces memory consumption when ● you have many small objects
  151. 151. Effective Python Programming – OSCON 2005 __slots__ Don't use __slots__ as some sort of ● type-checking hack __slots__ and subclassing == hurt ●
  152. 152. Effective Python Programming – OSCON 2005 Tying it all back together Java DOM Node ● Good example of a bad Python API ●
  153. 153. Effective Python Programming – OSCON 2005 Node.getChildNodes() Returns the child nodes of the current ● Node. Either: ● Node.childNodes or ● Make Node an iterator that iterates through it's children
  154. 154. Effective Python Programming – OSCON 2005 getValue()/setValue() Instead, just use node.value ● Or use a property if value is computed, ● or needs to be checked when set
  155. 155. Effective Python Programming – OSCON 2005 isSameNode() Implement a __eq__ method ● thisNode == otherNode Note that 'is' might not be right ● if you can have two Node instances pointing at the same part of the DOM
  156. 156. Effective Python Programming – OSCON 2005 compareDocumentPosition() Compares Node's document position to ● another Node. Instead, implement a .position attribute ● that can be compared: thisNode.position < otherNode.position Or even Node.__lt__, Node.__gt__ ● Could be a bit too clever/magic
  157. 157. Effective Python Programming – OSCON 2005 parent/child reference cycle Remember, a parent child reference ● cycle isn't a problem (So long as Node doesn't implement a __del__ method!) Still, don't create them unnecessarily ● References keep objects alive
  158. 158. Effective Python Programming – OSCON 2005 Wrapping Up Write Python code in Python ● Might involve un-learning some habits ● from other languages More information in the notes for these ● slides...
  159. 159. Effective Python Programming – OSCON 2005 Beautiful is better than ugly. ● Explicit is better than implicit. ● Simple is better than complex. ● Complex is better than complicated. ● Flat is better than nested. ● Sparse is better than dense. ● Readability counts. ● Special cases aren't special enough to break the rules. ● Although practicality beats purity. ● Errors should never pass silently. ● Unless explicitly silenced. ● In the face of ambiguity, refuse the temptation to guess. ● There should be one – and preferably only one – obvious way to do it. ● Although that way may not be obvious at first unless you're Dutch. ● Now is better than never. ● Although never is often better than *right* now. ● If the implementation is hard to explain, it's a bad idea. ● If the implementation is easy to explain, it may be a good idea. ● Namespaces are one honking great idea -- let's do more of those! ●
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×