Declaring a class level nested class?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Thu Dec 3 19:30:27 EST 2009


On Thu, 03 Dec 2009 06:59:43 -0800, cmckenzie wrote:

> It was late when I posted my example, so I don't think I made my
> question clear enough. I want to be able to construct a class level
> class variable, so its global to the class, then reference it from a
> class method. 

My brain is spinning, because you seem to be using terms in ways that 
aren't common in Python circles (or at least not familiar to *me*). This 
makes it really hard for me to be sure I understand you.

You say you want a "class level class variable" -- what do you mean by 
that? What's "class level" mean to you? When you say "class variable", do 
you mean "a variable that is a class", like a string variable is a 
variable that is a string, or do you mean an attribute of the class?

What do you mean by "global to the class"?


In your code sample, you say:

class module:
    nestedClass

but nestedClass isn't defined. Assuming nestedClass already exists, 
defined elsewhere (which implies it is NOT nested at all!) it would be 
syntactically legal, but meaningless. It would be as pointless as this:

class module:  # Define class
    [1, 2, 3]  # create a list and throw it away immediately

Where is nestedClass defined? Outside the class "module"? Inside the 
class? If so, where?

I *think* you mean you want a class attribute which happens to hold a 
class, which you want to be nested, but I'm not sure. If that's what you 
want, you would write it like this:

class module:
    # Horrible name, because module is a term already 
    # used in Python for something else

    class nestedclass:
        pass

Once you do that, you have a class "module" containing a nested class 
"nestedclass" which is available as a class-attribute 
"module.nestedclass".


> The declaration of a class level nestedClass class variable is wrong,
> but I was hoping someone could just say, "dummy, this is how to declare
> a class variable when you can't construct it just yet", 

Python doesn't need declarations. If you can't declare something, don't. 
You could put a placeholder and test for it:

class K:
    attribute = None  # Placeholder for the real value.
    def method(self):
        if self.attribute is None:
            print "attribute not initialised yet, this design sucks"
        else:
            print "do something useful"

or simply catch the AttributeError:

class K:
    def method(self):
        try:
            self.attribute
        except AttributeError:
            print "attribute not initialised yet, this design sucks"
        else:
            print "do something useful"


> or "you have to
> construct an empty version of nestedClass at the class level, then just
> re-construct it with any parameters during __init__".
> 
> class module:
>   nestedClass
> 
>   def __init__():
>      self.nestedClass = nested(10)
>      print self.nestedClass.nestedVar


That gives every instance of "module" its own instance-level attribute 
called "nestedClass".

It will only work if nested is a global-level function. To call the 
method called "nested" as you probably intend, you need to do this:

def __init__():
    self.nestedClass = self.nested(10)
    print self.nestedClass.nestedVar

which still makes nestedClass an attribute on the instance, not the 
class. To make it a class attribute, you have to refer to the class 
directly. Either of these will do, although the first is better because 
it will do the right thing if you subclass:

    self.__class__.nestedClass = self.nested(10)
    module.nestedClass = self.nested(10)

 
>   class nested():
>      nestedVar = 1
>      def __init__(self, value):
>         nestedVar = value
>         print "Initialized..."


Given that every instance is given an attribute nestedVar, what's the 
point of the class attribute "nestedVar"? It's never used.




-- 
Steven



More information about the Python-list mailing list