Question about classes and possible closure.

James Stroud jstroud at mbi.ucla.edu
Thu Feb 22 00:30:26 EST 2007


James Stroud wrote:
> Steven W. Orr wrote:
> 
>> This is all an intro learning experience for me, so please feel free 
>> to explain why what I'm trying to do is not a good idea.
>>
>> In the Cookbook, they have a recipe for how to create global constants.
>>
>> -----------------
>> class _const:
>>     class ConstError(TypeError): pass
>>     def __setattr__(self,name,value):
>>         if self.__dict__.has_key(name):
>>             raise self.ConstError, "Can't rebind const(%s)"%name
>>         self.__dict__[name]=value
>>
>> import sys
>> sys.modules[__name__]=_const()
>> ----------------
>>
>> I'd like to be able to create constants within a class. (Yes I 
>> understand that uppercase names is a far better and easier convention 
>> but this is a learning experience for me.)
>>
>> I can't get this to work, but my idea is that MyClass is defined thusly:
>>
>> class ConstError(TypeError): pass
>> class Myclass:
>>     def mprint(self):
>>         print "C1 = ", self._C1
>>
>>     # Define a subclass to create constants. It refs upself to access
>>     # the uplevel copy of self.
>>     class _const:
>>         class ConstError(TypeError): pass
>>         def __setattr__(_upself,name,value):
>>             if upself.__dict__.has_key(name):
>>                 raise self.ConstError, "Can't rebind const(%s)"%name
>>             else:
>>                 print "Just set something"
>>             upself.__dict__[name]=value
>>
>>     # I want the const instance to be contained in this class so I
>>     # instantiate here in the constructor.
>>     def __init__(self):
>>         upself = self
>>         upself.consts = const()
>>         upself.consts._C1 = 0
>>         setattr(upself.consts, "_C1", 44)
>>         self = upself
>>
>> Then the call in another file is this:
>> #! /usr/bin/python
>> from c2 import Myclass
>> foo = Myclass()
>> foo.mprint()
>> # end
>>
>> Is it possible to nest a class in another class and is it possible to 
>> make this work?
>>
>> TIA
>>
> 
> 
> I see no reason to nest classes, ever, as each creates a seperate name 
> space. Better would be to de-nest _const and make it available to all of 
> your classes, otherwise you have lost some of its reusability. A class 
> is esentially the definition of a behavior and so nesting assumes that 
> the nesting confers upon the outer class that having a nested class 
> changes its behavior. This is what composition is for. If you want a 
> reference to a class in your code, then make an assignment:
> 
> 
> # Const.py
> class ConstError(TypeError): pass
> 
> class Const:
>   def __setattr__(self, name, value):
>     if hasattr(self, name):
>       raise ConstError, "Can't rebind const(%s)" % name
>     else:
>       print "Just set something"
>     self.__dict__[name] = value
> 
> 
> # Myclass.py
> import Const
> 
> class Myclass:
> 
>      def mprint(self):
>          print "C1 = ", self.consts._C1
> 
>      def __init__(self):
>          self.consts = Const()
>          self.consts._C1 = 0
>          # This will raise an error!!!!
>          self.consts._C1 = 44
> 
> 
> This makes a lot more sense and follows the "flat is better than nested" 
>  rule. Notice how, otherwise, ConstError would be triple nested. Now you 
> can import Const and have constants in all your classes.
> 
> I also pythonized some of your code.
> 
> James

should be self.consts = Const.Const()

James



More information about the Python-list mailing list