The type function returns the datatype of any arbitrary object

>>> type(1)
<type 'int'>
>>> type(1.1)
<type 'float'>

>>> import sys
>>> sys.path.append('W:\\python\\tutorial')
  • >>> import odbchelper
>>> type(odbchelper)
<type 'module'>

The str coerces data into a string. Every datatype can be coerced into a string

>>> horsemen = ['war', 'pestilence', 'famine']
>>> horsemen
['war', 'pestilence', 'famine']
>>> str(horsemen)
"['war', 'pestilence', 'famine']"
>>> str(odbchelper)
"<module 'odbchelper' from 'W:\\python\\tutorial\\odbchelper.pyc'>"

dir returns a list of the attributes and methods of any object: modules, functions, strings, lists, dictionaries... pretty much anything.

>>> li=[]
>>> dir(li)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>> dir(odbchelper)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'buildConnectionString']

Works a bit like reflection does in Java. Allows the invocation of functions on an object at runtime

>>> li=["foo","bar"]
>>> getattr(li,"pop")
<built-in method pop of list object at 0x01258A30>
>>> getattr(li,"append")("moe")
>>> li
['foo', 'bar', 'moe']

We have seen list comprehension before. This combined with list filtering results in a very powerful combination

>>> li=["foo","bar","foo","one","n","zumo"]
>>> li
['foo', 'bar', 'foo', 'one', 'n', 'zumo']
>>> [elem for elem in li if len(elem)==1]
>>> [elem for elem in li if li.count(elem) > 1]
['foo', 'foo']

The first filter returns elements with string length = 1
The second filter returns only those elements that occur more than once in the list

In its most powerful form, the apihelper filters out only those methods which are callable. Create a file called (using ActivePython IDE, maybe)

def info(object, spacing=10, collapse=1):
    """Print methods and doc strings.
    Takes module, class, list, dictionary, or string."""
    methodList = [method for method in dir(object) if callable(getattr(object, method))]
    processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
    print "\n".join(["%s %s" %
                    processFunc(str(getattr(object, method).__doc__)))
                    for method in methodList])
if __name__ == "__main__":
    print info.__doc__

The statement

methodList = [method for method in dir(object) if callable(getattr(object, method))]

goes through every attribute and method defined in object and only prints out those for which callable returns true. When this is applied to the odbchelper created before

>>> import sys
>>> sys.path
['', 'C:\\WINDOWS\\system32\\', 'C:\\Python26\\DLLs', 'C:\\Python26\\lib', 'C:\\Python26\\lib\\plat-win', 'C:\\Python26\\lib\\lib-tk', 'C:\\Python26\\Lib\\site-packages\\pythonwin', 'C:\\Python26', 'C:\\Python26\\lib\\site-packages', 'C:\\Python26\\lib\\site-packages\\win32', 'C:\\Python26\\lib\\site-packages\\win32\\lib']
>>> sys.path.append('W:\\python\\tutorial')
>>> import apihelper
>>> import odbchelper
buildConnectionString Build a connection string from a dictionary of parameters. Returns string.

>>> 'a' and 'b'
>>> ' ' and 'b'
' '
>>> 'a' and ' '
>>> [] and {} and ''

'a' evaluates to TRUE and so does 'b'. and therefore returns the last TRUE value (left to right).
' ' evalautes to FALSE, so and always returns the FALSE value. In the same vein, [] is the first FALSE value encountered. By default, instances of classes are true in a boolean context, but you can define special methods in your class to make an instance evaluate to false

or works opposite to and. It returns the first TRUE value or the last FALSE value. If any value is true, or returns that value immediately

>>> 'a' or 'b'
>>> '' or 'b'
>>> 'a' or ''
>>> [] or {} or ''

>>> a="first"
>>> b="second"
>>> 1 and a
>>> 0 and a
>>> a or b
>>> 0 or b


>>> 1 and a or b
>>> 0 and a or b

so this syntax looks similar to the bool ? a : b expression. However, this syntax fails if you attempt the following

>>> a=""
>>> b="second"
>>> 1 and a or b

Since a is an empty string, which Python considers false in a boolean context, 1 and '' evalutes to ' ', and then ' ' or 'second' evalutes to 'second'. bool and a or b, will not work like bool ? a : b when a is false in a boolean context.

The real trick behind the and−or trick, then, is to make sure that the value of a is never false. One common way of doing this is to turn a into [a] and b into [b], then taking the first element of the returned list, which will be either a or b.

>>> (1 and [a] or [b])[0]

Since [a] is a non−empty list, it is never false. Even if a is 0 or ' ' or some other false value, the list [a] is true because it has one element. So is it worth all the trouble when you can do the above with an if statement?

Yes, because in some cases if statements are not allowed, such as in lambda functions.

lambda functions are in-line functions, or one−line mini−functions on the fly.
Lets define a normal function as follows

>>> def f(x):
...     return x*2
>>> f(3)

The same function can be done via lambda functions, either by assigining to a variable or in-line, as shown below

>>> g = lambda x:x*2
>>> g(3)
>>> (lambda x:x*2)(3)

The created earlier has a lambda function with the and-or trick (also described earlier)

processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)