Question about classes and possible closure.

Dustan DustanGroups at gmail.com
Wed Feb 21 18:21:25 EST 2007


On Feb 21, 4:30 pm, "Steven W. Orr" <ste... at syslang.net> 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

Looking ahead, this should be "self.consts._C1", not "self._Cl".

>      # Define a subclass to create constants. It refs upself to access
>      # the uplevel copy of self.

It's better to stick with the conventions. But regardless, you have to
be consistent, as we see in a moment.

>      class _const:
>          class ConstError(TypeError): pass

This is redundant. Even though this ConstError and the one defined
before the Myclass definition are in completely different scopes, so
there's no conflict, I doubt this is what you meant to do.

>          def __setattr__(_upself,name,value):

Notice your first argument here is "_upself", with an underscore.

>              if upself.__dict__.has_key(name):

Now you're using "upself", without an underscore, which is undefined.

>                  raise self.ConstError, "Can't rebind const(%s)"%name

Now you're using "self", which is also undefined.

>              else:
>                  print "Just set something"
>              upself.__dict__[name]=value

Once again, "upself" instead of "_upself".

Just follow the convention: always use "self".

>
>      # I want the const instance to be contained in this class so I
>      # instantiate here in the constructor.
>      def __init__(self):
>          upself = self

Why "upself = self"? You could just as easily use "self". Follow the
conventions.

>          upself.consts = const()

I'm guessing this is your error? That should be "upself.consts =
self._const()"

>          upself.consts._C1 = 0
>          setattr(upself.consts, "_C1", 44)

Obviously, this is going to raise an error, because you're redefining
_Cl.

>          self = upself

Again, why the weird juggling between self and upself? First of all,
self and upself are references to the same object right now, so "self
= upself" has no after-effect at all. Second of all, even if it did,
all it would be doing is reassigning the local variable "self" to a
different object; it has no effect on the object you're working with.

> 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?

Yes, it is possible to nest a class in another class. Yes, it is
possible to make this work. However, it is good practice to post your
error message along with your code, so we don't have to guess.

Here's an untested rewrite of your code:

class Myclass:
     def mprint(self):
         print "C1 = ", self.consts._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 _upself.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):
         self.consts = const()
         self.consts._C1 = 0
         # This will raise an error!!!!
         setattr(self.consts, "_C1", 44)

> TIA
>
> --
> Time flies like the wind. Fruit flies like a banana. Stranger things have  .0.
> happened but none stranger than this. Does your driver's license say Organ ..0
> Donor?Black holes are where God divided by zero. Listen to me! We are all- 000
> individuals! What if this weren't a hypothetical question?
> steveo at syslang.net




More information about the Python-list mailing list