Quirks

Slices

Slices can be used not only in the right side of assignment, but also in the left one.

   1 >>> a = [1,2,3,4]
   2 >>> a[1:3] = [5]
   3 >>> a
   4 [1,5,4]

Slices have third argument: step. Here we'll select all the odd elements of a list:

   1 >>> a = [1,2,3,4]
   2 >>> a[0:4:2]
   3 [1, 3]

There's an example of awfully quirky code in http://www.python.org/dev/peps/pep-3333/#the-server-gateway-side, where they use triple assignment with slices like this:

   1 >>> a=[1]
   2 >>> b=[2]
   3 >>> c=[3]
   4 >>> a=b[:]=c
   5 >>> a
   6 [3]
   7 >>> b
   8 [3]
   9 >>> c
  10 [3]
  11 >>> c.append(1)
  12 >>> a
  13 [3, 1]
  14 >>> c
  15 [3, 1]
  16 >>> b
  17 [3]

Sprintf-style formatting

If you want to protect the percent sign in sprintf-style template, use double percent sign. This might be used for secondary expansion within the same template:

   1 >>> attachdir ="/home"; filename = "file"
   2 >>> dst = "%s/%s%%d.png" % (attachdir, fn)
   3 >>> dst
   4 '/home/file%d.png'
   5 >>> dst % 1
   6 '/home/file1.png'

Sprintf supports expansion not only from tuple, but from a dict as well:

   1 myDict = {'solo': 'Han Solo', 
   2           'jabba': 'Jabba the Hutt'}
   3 print "%(solo)s was captured by %(jabba)s." % myDict   # Han Solo was captured by Jabba the Hutt.

Another nice usage of sprintf is to combine it with locals/globals to output values of all the variables in the namespace.

Protocols for getters/setters/deleters: property and descriptor

There was a popular tradition in various programming languages, such as Java, to specify methods, called setters and getters in classes of APIs (Django or GTK are examples of API; by saying API I mean libraries and/or engines) to be called when the value of a field (term field is equivalent to term property, equivalent to instance variable) of that class's object is get or set. Python adopts this tradition through property and descriptor protocols, supplying getters, setters and deleters.

property

Suppose that you want an attribute to be dynamically calculated from values of other attributes. It makes sense in case those get changed:

   1 class Rectangle(object):
   2     def __init__(self, width, height):
   3         self.width = width
   4         self.height = height
   5     @property
   6     def area(self):
   7         return self.width * self.height
   8 
   9 rec = Rectangle(5, 10)
  10 print rec.area
  11 # result is 50

Built-in function property can be used as a decorator for a getter-method. In this example we used rec.area as if it was a variable, not a method, thanks to @property decorator. setter and deleter decorators are called @foo.setter and @foo.deleter, where foo is the name of property, you want to set.

http://www.python.org/dev/peps/pep-0318/

There's also a built-in class, named property. Given set, get and delete methods, it creates a property from them:

   1   class C(object):
   2       def getx(self): return self._x
   3       def setx(self, value): self._x = value
   4       def delx(self): del self._x
   5       x = property(getx, setx, delx, "I'm the 'x' property.")

descriptor

http://docs.python.org/howto/descriptor.html

pdb

pdb can debug function, called from another module. It has 2 types of syntax for that:

   1 $ python -m pdb main
   2 (Pdb) import sys
   3 (Pdb) sys.path.append("/home/user/path/to/another/module")
   4 (Pdb) import another_module
   5 (Pdb) b another_module:356
   6 Breakpoint 1 at /home/user/path/to/another/module/another_module.py:356

Note that you have to see "another_module" in your current namespace to set breakpoint within, thus you import it. Also, note that you shouldn't set breakpoint onto function definition line, cause it is not executed and never reached! For that purpose you can use alternative syntax b module:function.

winpdb

Links:

burkov.net: Courses/Python (last edited 2014-05-15 14:24:05 by Bob)