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