Wednesday, June 20, 2007

static fields in python

In python language the classes are behaving some times different then in other languages, for example the static fields. If you'll read on the net about static fields in python you'll get many solutions one more complex then the other. The simplest method I've stumble upon when coding is to declare and initialize the attribute in the class not in the constructor like in the example below:

#!/usr/bin/python

class father(object):
_class_atributes = []
_object_atributes = None

def __init__(self, cls_att, obj_att) :
# init the obj att
self._object_atributes = []

self._class_atributes.append(cls_att)
self._object_atributes.append(obj_att)

def __str__(self) :
print 'called by ' + str(self.__class__)
print 'class att: ' + str(self._class_atributes)
print 'object att: ' + str(self._object_atributes)
return ""

f1 = father(1, 1);
str(f1);
f2 = father(2, 2);

str(f1);
str(f2);

and the output is :


[andrei@aculapov scripts]# ./example1.py
called by
class att: [1]
object att: [1]
called by
class att: [1, 2]
object att: [1]
called by
class att: [1, 2]
object att: [2]
[andrei@aculapov scripts]#


As you can see the two instances of the father class share the _class_atributes list. This is because it's created by the class and not at instance creation.

Now comes an inheritance issue. If you make some class or classes that inherits our father class, then _class_atribute will be common to all objects that inherited our base class. So let us add two more classes :


class One(father):

def __init__(self):
super(One, self).__init__(1, 1)

class Two(father):

def __init__(self):
super(Two, self).__init__(2, 2)

one = One();
str(one);
two = Two();

str(one);
str(two);


and the new output it will be:


[root@aculapov scripts]# ./inh.py
called by
class att: [1]
object att: [1]
called by
class att: [1, 2]
object att: [1]
called by
class att: [1, 2]
object att: [2]
[root@aculapov scripts]#



Nice thing I can say!


Wednesday, May 23, 2007

Generic database proxy that separates the reads and writes based on the caller object

One problem that I faced this days was to pass the proper database connection based on the caller class. The task was to separate the writes and reads to and into the database, to use one database connection for the writes and another for the reads. It wasn't hard but I had to search a little the python documentation . The inspect module can do wonders if you know how to use it. The plan was to get the __class__ of the caller object by getting the previous frame from the caller stack and check the class type.
import inspect


class DatabaseProxy :
__writeConn = None
__readConn = None
__readClass = None
def __init__(self, writeConnection, readConnection, readClass) :
self.__writeConn = writeConnection
self.__readConn = readConnection
self.__readClass = readClass

def getConnection(self):
returnConnection = None
# get the previos frame from the database
frame_dict = inspect.currentframe().f_back.f_locals
try:

if frame_dict.has_key('self') and self.is_write_class(frame_dict['self'], self.__readClass):
# this is the read event
returnConnection = self.__readConn
else:
print 'write'
# this is the write event
returnConnection = self.__writeconn
finally:
del frame_dict
return returnConnection

def is_write_class(self, instance, class_type):

# get the instance's class
instance_class = instance.__class__

# test the instance_class to be the same type as class_type
# or to be a class that extends class_type
if len([object for object in inspect.getmro(instance_class) if (clas is class_type)]) != 0 :
return True

return False

The easy part was that all the read access to the database was done throw one class(QuerySet) or throw a class that extends this QuerySet class.