Skip to content

Python

main

You can use this to detect if a script was imported or ran standalone. An example with two scripts a.y:

main
1
2
3
#!/usr/bin/python
print "a.py : Hello from %s!" % __name__
import b

and b.py

main
1
2
3
4
5
6
7
#!/usr/bin/python
print "b.py : Hello from %s!" % __name__

if __name__ == '__main__':
    print("Standalone")
else:
    print "imported", __name__

If you run a.py you get :

imported
1
2
3
a.py : Hello from __main__!
b.py : Hello from b!
imported b

Note: inside a.py the name is main but once b is imported name becomes b. And so the test will see that and detect it is imported.

Running b.py will give :

standalone
b.py : Hello from __main__!
Standalone

Of course there is never a.py involved so it is top level main all along, and the standalone version is detected.

glob

Globbing is pattern matching based on wildcard patterns, a glob is used to refer to the pattern used so : the "glob" to match all header is *.h

Read all html files in the current directory :

glob
1
2
3
4
for filename in glob.iglob(os.path.join('.','*.html')):
    with open(filename) as f:
        content = f.read()
        print content

dictionary dump

You can print all variables of a dictionary with the aid of the vars function:

dump dict
print vars(object)

If also want it pretty printed, you can import pprint and use :

pretty print
pprint.pprint (vars(object))

mongodb

debian installation

On debian at least, the package python-pymongo is in the aptitude list, but it is sadly broken.

If this little program :

pymongo
1
2
3
4
5
6
#!/usr/bin/python
import pymongo
from pymongo import MongoClient

client = MongoClient('localhost', 27017)
print(client);

Fails with :

error
"ImportError: cannot import name MongoClient" 

This is most likely the problem. Uninstall it and reinstall it using pip:

pip
1
2
3
apt-get purge python-pymongo
apt-get install python-pip
pip install pymongo

This gives me :

works
./mongo.py
MongoClient('localhost', 27017)

Probably always prefer pip over apt Or use easy_install/eggs (see above)

terse example

example
#!/usr/bin/python
import pymongo
from pymongo import MongoClient

client = MongoClient('localhost', 27017)

database = client.test
print(database);
print(database.collection_names());

collection = database.testcoll
print (collection)

data = { "name" : "value" };
post_id = collection.insert(data);

print(post_id);
print(database.collection_names());

for line in collection.find():
    print(line);

collection.drop();

for line in collection.find():
    print(line);

programming

lists

These are like arrays, you can fill them directly :

initialization

lists
l = [1,2,3]

Or with a range, note that range() already gives a list so this:

range
l = range(1,10)

Would give you :

output
print l 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

And this :

array from range
l = [range(1,10)] 

Would result in

output
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]

Also you can use a format string to fill and format the contents :

format string
1
2
3
feedlist = [11,22,33]
l = ['an item %d is %d' % (x,x) for x in feedlist]
print l

Result

output
['an item 11 is 11', 'an item 22 is 22', 'an item 33 is 33']

This works like a printf in c, you need to provide as much arguments for % () as there are format codes (like c) and it does not matter if they appear twice(like c). Th ex can then be provided by a for loop or again a range :

format string
x = ['ok %d,%d' % (y,y) for y in range(1,10)];
print (x)

Gives :

output
['ok 1,1', 'ok 2,2', 'ok 3,3', 'ok 4,4', 'ok 5,5', 'ok 6,6', 'ok 7,7', 'ok 8,8', 'ok 9,9']

Also you can have named format strings, for example :

named format string
1
2
3
t = {'hi': 'there', 'lo': 'hihihe'}
tuplist = ['a subsituted value : %(hi)s ' % t ];
print tuplist

Will substitute the tuple value of key 'hi' and print :

output
['a subsituted value : there']

manipulating manually

Later..

threading

You can use the threading module for that.

UnboundLocalError: local variable referenced before assignment

This occurs whenever you do something like this :

UnboundLocalError
1
2
3
4
5
6
7
8
#!/usr/bin/python
x = 10      # global x

def add():
    x = x + 10  # local x = undefined + 10
    print x

add()

The problem is that within the function, x = initialized (again) as a local variable, and thus has no value. You can fix it by using the global keyword.

use global
1
2
3
4
5
6
7
8
9
#!/usr/bin/python
x = 10

def add():
    global x
    x = x + 10
    print x

add()

import

importing modules can take a number of forms :

import
1
2
3
4
import time

time.sleep(2)
print ("Done")

However when you want to use sleep without having to put the module in front of it you will get :

output
NameError: name 'sleep' is not defined

To use sleep by itself import time like this :

named import
1
2
3
4
from time import sleep

sleep(2)
print ("Done")

Note however that you now have only imported sleep !!, for instance time.sleep(2) does not work anymore, because module time is NOT imported anymore. You could do this to get both versions working :

now you can't use time.sleep()
1
2
3
4
5
import time
form time import sleep
sleep(1)
time.sleep(1)
print("Done")

The last way is import 'as' a local name.

1
2
3
4
5
6
7
8
#!/usr/bin/python
import time as mytime
from time import sleep as mysleep

mysleep(2)
mytime.sleep(2)
#anothername(1)
print("Done")

Note that in this case, sleep() and time.sleep() are not recognized, only mysleep() and mytime.sleep()

modules

Simply import a file by it's name and use a function :

module.py

modules
def modfunc(v):
    print v

caller.py

import
import module
module.modfunc("hello");

Or if you want to use modfunc without the module name :

named import
1
2
3
4
5
import module
from module import modfunc

module.modfunc("hello")
modfunc("there") # will fail without the second import line

Call :

call
1
2
3
python caller.py
hello
there

annotations

You've seen them before as a line starting with @, like in autobahn's exportRpc:

annotations
1
2
3
@exportRpc
def snd(self,msg):
    ...

From : http://legacy.python.org/dev/peps/pep-3107/

  1. function annotations, both for parameters and return values, are completely optional.
  2. Function annotations are nothing more than a way of associating arbitrary Python expressions with various parts of a function at compile-time. The only way that annotations take on meaning is when they are interpreted by third-party libraries.
  3. Following from point 2, this PEP makes no attempt to introduce any kind of standard semantics, even for the built-in types. This work will be left to third-party libraries.

So... python defines the syntax but attached no meaning to annotations. In the autobahn example the third party library @exportRpc indeed exports the function below it as an Rpc call to the server. For instance :

annotations
1
2
3
4
5
6
7
8
9
@exportRpc
def help(self):
    helpmessage = "help: this messagen" \
                "start: start new gamen"  \
                "who: list who is presentn"  \
                "clr: clear your chat screenn" \
                "dim(w,h): set game dimensionsn"  \

return helpmessage;

json pretty print

Also possible with standard python install. For instance pretty printing the output from klopt server :

json pp
./status.py | python -m json.tool

Or of course

json pp
python -m json.tool < src.json

troubleshooting