class variables

Colin J. Williams cjw at sympatico.ca
Sun Jul 30 08:35:44 EDT 2006


Andre Meyer wrote:
> Hi all
> 
> I am trying to understand the magic of Python's class variables and 
> tried the following code (see below).
> 
> Just out of curiosity, I tried to define a property that provides access 
> to a seemingly instancae variable which is in fact a class variable. All 
> seems to work fine (case 4), but when a custom object is assigned, an 
> instance variable is created instead of using theproerty (case 5).
> 
> What goes wrong here? What is the difference between cases 4 and 5? How 
> can case 5 be fixed?
> 
> thanks a lot for your help
> Andre
> 
> Code Listing
> =========
> 
> print; print "*** Case 1 ***"; print
> 
> class C1(object):
>    
>     v = None
>    
>     def __init__(self, value):
>         print '-', self.v
>         self.v = value
>    
>     def value(self):
>         return self.v
>    
> a1 = C1(1)
> b1 = C1(2)
> print a1.value()
> 
> print; print "*** Case 2 ***"; print
> 
> class C2(object):
>    
>     v = None
>    
>     def __init__(self, value):
>         print '-', self.v
>         self.__class__.v = value
>    
>     def value(self):
>         return self.__class__.v
>    
> a2 = C2(1)
> b2 = C2(2)
> print a2.value()
> 
> print; print "*** Case 3 ***"; print
> 
> class C3(object):
>    
>     v = 5
>    
>     def __init__(self, value):
>         print '-', self.v
>         self.v = self.v + value
>    
>     def value(self):
>         return self.v
>    
> a3 = C3(1)
> b3 = C3(2)
> print a3.value()
> print a3.v
> print a3.__class__.v
> 
> print; print "*** Case 4 ***"; print
> 
> class V4(list):
>     def work(self):
>         return 'done'
>    
> class C4(object):
>    
>     def __set_v(self, v): self.__class__.__v = v   
>     def __get_v(self): return self.__class__.__v
>     def __del_v(self): del self.__class__.__v
>     v = property(__get_v, __set_v, __del_v, 'make class variable')
>     v = V4()
>    
>     def __init__(self, value):
> 
>         print '-', self.v
>         self.v.append(value)
>         print '+', self.v
>    
>     @classmethod
>     def value(self):
>         print self.v.work()
>         return self.v
>    
> 
> a4 = C4(1)
> b4 = C4(2)
> print a4.value()
> print a4.v
> print a4.__class__.v
> print a4.v.work()
> 
> 
> print; print "*** Case 5 ***"; print
> 
> class V5(object):
>     def __init__(self, i):
>         self.i = i
>        
>     def work(self):
>         return 'done', self.i
>    
> class C5(object):
>    
>     def __set_v(self, v): self.__class__.__v = v   
>     def __get_v(self): return self.__class__.__v
>     def __del_v(self): del self.__class__.__v
>     v = property(__get_v, __set_v, __del_v, 'make class variable')
>     v = None
>    
>     def __init__(self, value):
> 
>         print '-', self.v
>         self.v = V5(value)
>         print '+', self.v
> #        print self.__class__.__dict__
> #        print self.__dict__
>    
>     @classmethod
>     def value(self):
>         print self.v.work()
>         return self.v
>    
> 
> a5 = C5(1)
> b5 = C5(2)
> print a5.value()
> print a5.v
> print a5.__class__.v
> print a5.v.work()
> 
> 
> Output
> =====
> 
> 
> *** Case 1 ***
> 
> - None
> - None
> 1
> 
> *** Case 2 ***
> 
> - None
> - 1
> 2
> 
> *** Case 3 ***
> 
> - 5
> - 5
> 6
> 6
> 5
> 
> *** Case 4 ***
> 
> - []
> + [1]
> - [1]
> + [1, 2]
> done
> [1, 2]
> [1, 2]
> [1, 2]
> done
> 
> *** Case 5 ***
> 
> - None
> + <__main__.V5 object at 0x00AFE0D0>
> - None
> + <__main__.V5 object at 0x00AFE110>
> Traceback (most recent call last):
>   File "classvariables.py", line 121, in ?
>     print a5.value ()
>   File "classvariables.py", line 115, in value
>     print self.v.work()
> AttributeError: 'NoneType' object has no attribute 'work'
> 
André,

I would have expected a5.v to be equal to b5.v, otherwise what is the 
value of a class variable?

I get:
[Dbg]>>> a5.v == b5.v
False

I hope that one of the wizards will respond.

Colin W.




More information about the Python-list mailing list