469,636 Members | 1,555 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,636 developers. It's quick & easy.

Question about classes and possible closure.

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

--
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
Feb 21 '07 #1
3 1119
On Feb 21, 4:30 pm, "Steven W. Orr" <ste...@syslang.netwrote:
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
Feb 21 '07 #2
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
Feb 22 '07 #3
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
Feb 22 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

27 posts views Thread by Ted Lilley | last post: by
7 posts views Thread by cwhite | last post: by
7 posts views Thread by Csaba Gabor | last post: by
4 posts views Thread by emailscotta | last post: by
26 posts views Thread by Cliff Williams | last post: by
11 posts views Thread by Huayang Xia | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.