Declaring a class level nested class?

Discussion in 'Python' started by cmckenzie, Dec 3, 2009.

  1. cmckenzie

    cmckenzie Guest

    Hi.

    I'm new to Python, but I've managed to make some nice progress up to
    this point. After some code refactoring, I ran into a class design
    problem and I was wondering what the experts thought. It goes
    something like this:

    class module:
    nestedClass

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

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

    I can't figure out what the correct way to construct the "nested"
    class so it can belong to "module".

    I want a class level construct of "nested" to belong to "module", but
    I keep getting nestedClass isn't defined.

    My example isn't great or 100% accurate, but I hope you get the idea.

    Thanks.
    cmckenzie, Dec 3, 2009
    #1
    1. Advertising

  2. cmckenzie

    Chris Rebert Guest

    On Wed, Dec 2, 2009 at 8:55 PM, cmckenzie <> wrote:
    > Hi.
    >
    > I'm new to Python, but I've managed to make some nice progress up to
    > this point. After some code refactoring, I ran into a class design
    > problem and I was wondering what the experts thought. It goes
    > something like this:
    >
    > class module:
    >   nestedClass
    >
    >   def __init__():
    >      self.nestedClass = nested()
    >      print self.nestedClass.nestedVar
    >
    >   class nested():
    >      nestedVar = 1
    >      def __init__(self):
    >         print "Initialized..."
    >
    > I can't figure out what the correct way to construct the "nested"
    > class so it can belong to "module".
    >
    > I want a class level construct of "nested" to belong to "module", but
    > I keep getting nestedClass isn't defined.


    Here's the scoping reason why it fails (remember that the nested class
    is a class variable of the containing class):

    <BEGIN PENDING FAQ SUBMISSION>

    Why do I get errors when accessing class variables (a.k.a. static variables)?
    -------------------------------------------------------------------------------------
    If you try something like the following::

    class Foo(object):
    class_variable = 42

    def method(self, x):
    return x + class_variable


    Foo().method(7)

    You'll get an error about Python being unable to find the class variable::

    Traceback (most recent call last):
    ...
    NameError: global name 'class_variable' is not defined

    This is because class-level scope is not consulted when looking up
    plain names in methods. When looking up a name, the following scopes
    are consulted, in order: Local variables, Variables in nested
    functions, Global variables, and finally, Built-ins.

    To refer to class variables, you must be more explicit. There are several
    ways to go about it:

    * Refer to the class by name::

    def method1(self, x):
    return x + Foo.class_variable

    * Refer to the class of the object dynamically. If you class is
    subclassed, this will allow the subclasses to override the value of
    the class variable. ::

    def method2(self, x):
    return x + self.__class__.class_variable

    * Exploit the fact that attribute lookups on an object fall back to
    its class. Be warned that if you have both instance and class variables
    with the same name, the instance variable will shadow
    the class variable. ::

    def method3(self, x):
    return x + self.class_variable

    * If your method is not truly an instance method
    (i.e. does not utilize ``self``), make it a class method ::

    @classmethod
    def method4(cls, x):
    return x + cls.class_variable

    <END FAQ EXCERPT>

    However, there's pretty much no reason to nest classes anyway in
    Python (it's not Java!). Just make them both top-level in the file. If
    one class is only used internally in the module, just use the normal
    private naming convention of starting its name with an underscore.

    Also note that class names should generally use StudlyCaps, and that
    naming a class "module" is rather confusing.

    Cheers,
    Chris
    --
    If the Python.org webmasters are listening, add the FAQ entry already!
    http://blog.rebertia.com
    Chris Rebert, Dec 3, 2009
    #2
    1. Advertising

  3. cmckenzie

    inhahe Guest

    it seems to me like it should work just fine if you just take out the
    second line where it just says nestedClass

    On Wed, Dec 2, 2009 at 11:55 PM, cmckenzie <> wrote:
    > Hi.
    >
    > I'm new to Python, but I've managed to make some nice progress up to
    > this point. After some code refactoring, I ran into a class design
    > problem and I was wondering what the experts thought. It goes
    > something like this:
    >
    > class module:
    >   nestedClass
    >
    >   def __init__():
    >      self.nestedClass = nested()
    >      print self.nestedClass.nestedVar
    >
    >   class nested():
    >      nestedVar = 1
    >      def __init__(self):
    >         print "Initialized..."
    >
    > I can't figure out what the correct way to construct the "nested"
    > class so it can belong to "module".
    >
    > I want a class level construct of "nested" to belong to "module", but
    > I keep getting nestedClass isn't defined.
    >
    > My example isn't great or 100% accurate, but I hope you get the idea.
    >
    > Thanks.
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >
    inhahe, Dec 3, 2009
    #3
  4. cmckenzie wrote:
    > Hi.
    >
    > I'm new to Python, but I've managed to make some nice progress up to
    > this point. After some code refactoring, I ran into a class design
    > problem and I was wondering what the experts thought. It goes
    > something like this:
    >
    > class module:
    > nestedClass
    >
    > def __init__():
    > self.nestedClass = nested()
    > print self.nestedClass.nestedVar
    >
    > class nested():
    > nestedVar = 1
    > def __init__(self):
    > print "Initialized..."
    >
    > I can't figure out what the correct way to construct the "nested"
    > class so it can belong to "module".
    >
    > I want a class level construct of "nested" to belong to "module", but
    > I keep getting nestedClass isn't defined.
    >
    > My example isn't great or 100% accurate, but I hope you get the idea.
    >
    > Thanks.
    >

    class module:

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

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

    Python will not look into the current class scope when trying to resolve
    "nested", that is why the explicit call including the scope is required.
    The code above runs fine with python 2.5.

    Jean-Michel
    Jean-Michel Pichavant, Dec 3, 2009
    #4
  5. Chris Rebert wrote:
    > On Wed, Dec 2, 2009 at 8:55 PM, cmckenzie <> wrote:
    >
    >> Hi.
    >>
    >> I'm new to Python, but I've managed to make some nice progress up to
    >> this point. After some code refactoring, I ran into a class design
    >> problem and I was wondering what the experts thought. It goes
    >> something like this:
    >>
    >> class module:
    >> nestedClass
    >>
    >> def __init__():
    >> self.nestedClass = nested()
    >> print self.nestedClass.nestedVar
    >>
    >> class nested():
    >> nestedVar = 1
    >> def __init__(self):
    >> print "Initialized..."
    >>
    >> I can't figure out what the correct way to construct the "nested"
    >> class so it can belong to "module".
    >>
    >> I want a class level construct of "nested" to belong to "module", but
    >> I keep getting nestedClass isn't defined.
    >>

    >
    > Here's the scoping reason why it fails (remember that the nested class
    > is a class variable of the containing class):
    >
    > [snip interesting reminder/faq]
    >
    > However, there's pretty much no reason to nest classes anyway in
    > Python (it's not Java!).

    A little bit off topic,ahere is a nested class pattern I'm using quite
    often :

    class Device
    """Holds the different device services."""

    class OS: # UPPERCASE means it holds constants
    """Operating system of one device."""
    VXWORKS = 'vxWorks'
    ECOS = 'ecos'

    def init(self, _os = None):
    self.os = _os

    device = Device(Device.OS.VXWORKS)

    Whenever I get a Device instance in my code I can match its OS without
    tedious imports:

    # no "from whatever import Device" is required
    if device.os is device.OS.VXWORKS:
    print 'you are using vxWorks'


    I'm using this pattern whenever I can now:
    1/ it removes all magically 'inside code' defined strings or numbers,
    only class attributes are used.
    2/ if required, it allows to write complete and detailed documentation
    for nested class constants
    3/ you can match attributes with the nested class values without further
    import, everything is accessible from the instance itself

    JM
    Jean-Michel Pichavant, Dec 3, 2009
    #5
  6. cmckenzie

    Lie Ryan Guest

    On 12/3/2009 3:55 PM, cmckenzie wrote:
    > I can't figure out what the correct way to construct the "nested"
    > class so it can belong to "module".
    >


    which one you want?

    1. The Outside's class contains a nested class
    class Outside(object):
    class Inside(object):
    ...

    2. The Outside's class contains an instance of the nested class
    class Outside(object):
    class inside(object):
    ...
    inside = inside()

    3. The Outside's instance contains an instance of the nested class
    class Outside(object):
    class Inside(object):
    ...
    def __init__(self):
    self.inside = Outside.Inside()


    4.
    Lie Ryan, Dec 3, 2009
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. E11
    Replies:
    1
    Views:
    4,736
    Thomas Weidenfeller
    Oct 12, 2005
  2. pabbu
    Replies:
    8
    Views:
    719
    Marc Boyer
    Nov 7, 2005
  3. Replies:
    2
    Views:
    668
    mlimber
    Jun 9, 2006
  4. request@no_spam.com
    Replies:
    5
    Views:
    420
  5. cmckenzie

    Declaring a class level nested class?

    cmckenzie, Dec 3, 2009, in forum: Python
    Replies:
    3
    Views:
    275
    Steven D'Aprano
    Dec 4, 2009
Loading...

Share This Page