What is the reason for defining classes within classes in Python?

Discussion in 'Python' started by vasudevram, Apr 23, 2013.

  1. vasudevram

    vasudevram Guest

    vasudevram, Apr 23, 2013
    #1
    1. Advertising

  2. vasudevram

    Ian Kelly Guest

    On Tue, Apr 23, 2013 at 3:50 PM, vasudevram <> wrote:
    >
    > Hi list,
    >
    > I saw an example of defining a class within another class, here, in the docs for peewee, a simple ORM for Python:
    >
    > http://peewee.readthedocs.org/en/latest/peewee/quickstart.html
    >
    > In what way is this useful?


    In that particular case they're just using it as a namespace. Django
    does the same thing.
     
    Ian Kelly, Apr 23, 2013
    #2
    1. Advertising

  3. vasudevram

    vasudevram Guest

    On Wednesday, April 24, 2013 3:52:57 AM UTC+5:30, Ian wrote:
    > On Tue, Apr 23, 2013 at 3:50 PM, vasudevram wrote:
    >
    > >

    >
    > > Hi list,

    >
    > >

    >
    > > I saw an example of defining a class within another class, here, in the docs for peewee, a simple ORM for Python:

    >
    > >

    >
    > > http://peewee.readthedocs.org/en/latest/peewee/quickstart.html

    >
    > >

    >
    > > In what way is this useful?

    >
    >
    >
    > In that particular case they're just using it as a namespace. Django
    >
    > does the same thing.


    Not clear. An example or more explanation might help, if you can. Thanks.
     
    vasudevram, Apr 24, 2013
    #3
  4. vasudevram

    alex23 Guest

    On Apr 24, 9:13 am, vasudevram <> wrote:
    > On Wednesday, April 24, 2013 3:52:57 AM UTC+5:30, Ian wrote:
    > > On Tue, Apr 23, 2013 at 3:50 PM, vasudevram  wrote:
    > > > I saw an example of defining a class within another class
    > > > In what way is this useful?

    >
    > > In that particular case they're just using it as a namespace.

    >
    > Not clear. An example or more explanation might help, if you can. Thanks.


    Namespaces are used to allow for the same label to be applied to
    different concepts without the labels conflicting with each other. If
    I was writing a program that dealt with the mathematics of morality, I
    might want to use the sine function and refer to it in the standard
    way as 'sin', and I might also want to store a value representing your
    lack of goodness as 'sin'. As you can't use the same label in the same
    scope to refer to two different objects, one way of dealing with this
    that lets you still use what you feel are the most appropriate names
    is to put them into a namespace. So you could express this as:

    class Math(object):
    sin = function()

    class Morality(object):
    sin = True

    Then in your code you can clearly distinguish between the two by using
    Math.sin and Morality.sin. Modules & packages are also namespaces, so
    in this example we'd replace the Math class with `import math`, which
    has a sin function defined within it.

    A nested class definition will be defined as an attribute of the class
    its defined within:

    >>> class Outer(object):

    .... foo = 'FOO'
    .... class Inner(object):
    .... bar = 'BAR'
    ....
    >>> Outer.Inner

    <class '__main__.Inner'>
    >>> Outer.Inner.bar

    'BAR'

    With peewee, the Model class looks for a Meta attribute and uses
    attributes on it to perform some tasks, like where to retrieve/store
    the model data. This allows for a way of distinguishing between
    attributes used to define fields, and attributes needed for those
    tasks. It also means your Models can use field names that the class
    would otherwise reserve for its own internal purposes:

    class DatabaseDetails(Model):
    # these attributes are fields
    database = CharField()
    owner = CharField()

    # ...but the Meta attribute isn't
    class Meta:
    # these attributes are used by the Model class
    database = db

    Here, database as a field is a text string that could contain a
    database name, while DatabaseDetails.Meta.database contains a
    reference to an actual database where the DatabaseDetails record would
    be stored.
     
    alex23, Apr 24, 2013
    #4
  5. vasudevram

    vasudevram Guest

    On Wednesday, April 24, 2013 6:20:36 AM UTC+5:30, alex23 wrote:
    > On Apr 24, 9:13 am, vasudevram <> wrote:
    >
    > > On Wednesday, April 24, 2013 3:52:57 AM UTC+5:30, Ian wrote:

    >
    > > > On Tue, Apr 23, 2013 at 3:50 PM, vasudevram  wrote:

    >
    > > > > I saw an example of defining a class within another class

    >
    > > > > In what way is this useful?

    >
    > >

    >
    > > > In that particular case they're just using it as a namespace.

    >
    > >

    >
    > > Not clear. An example or more explanation might help, if you can. Thanks.

    >
    >
    >
    > Namespaces are used to allow for the same label to be applied to
    >
    > different concepts without the labels conflicting with each other. If
    >
    > I was writing a program that dealt with the mathematics of morality, I
    >
    > might want to use the sine function and refer to it in the standard
    >
    > way as 'sin', and I might also want to store a value representing your
    >
    > lack of goodness as 'sin'. As you can't use the same label in the same
    >
    > scope to refer to two different objects, one way of dealing with this
    >
    > that lets you still use what you feel are the most appropriate names
    >
    > is to put them into a namespace. So you could express this as:
    >
    >
    >
    > class Math(object):
    >
    > sin = function()
    >
    >
    >
    > class Morality(object):
    >
    > sin = True
    >
    >
    >
    > Then in your code you can clearly distinguish between the two by using
    >
    > Math.sin and Morality.sin. Modules & packages are also namespaces, so
    >
    > in this example we'd replace the Math class with `import math`, which
    >
    > has a sin function defined within it.
    >
    >
    >
    > A nested class definition will be defined as an attribute of the class
    >
    > its defined within:
    >
    >
    >
    > >>> class Outer(object):

    >
    > ... foo = 'FOO'
    >
    > ... class Inner(object):
    >
    > ... bar = 'BAR'
    >
    > ...
    >
    > >>> Outer.Inner

    >
    > <class '__main__.Inner'>
    >
    > >>> Outer.Inner.bar

    >
    > 'BAR'
    >
    >
    >
    > With peewee, the Model class looks for a Meta attribute and uses
    >
    > attributes on it to perform some tasks, like where to retrieve/store
    >
    > the model data. This allows for a way of distinguishing between
    >
    > attributes used to define fields, and attributes needed for those
    >
    > tasks. It also means your Models can use field names that the class
    >
    > would otherwise reserve for its own internal purposes:
    >
    >
    >
    > class DatabaseDetails(Model):
    >
    > # these attributes are fields
    >
    > database = CharField()
    >
    > owner = CharField()
    >
    >
    >
    > # ...but the Meta attribute isn't
    >
    > class Meta:
    >
    > # these attributes are used by the Model class
    >
    > database = db
    >
    >
    >
    > Here, database as a field is a text string that could contain a
    >
    > database name, while DatabaseDetails.Meta.database contains a
    >
    > reference to an actual database where the DatabaseDetails record would
    >
    > be stored.


    Actually, I did know what namespaces are in general. What I didn't get was how the inner class Meta in the peewee example was being used as a namespace. Your explanation makes things very clear. Thank you.

    Just one other doubt:

    > >>> Outer.Inner

    >
    > <class '__main__.Inner'>
    >


    In the above output, I would have thought Python would print __main__.Outer..Inner or Outer.Inner instead of __main__.Inner, since Inner is an attribute of Outer?
     
    vasudevram, Apr 24, 2013
    #5
  6. vasudevram

    Peter Otten Guest

    vasudevram wrote:

    > On Wednesday, April 24, 2013 6:20:36 AM UTC+5:30, alex23 wrote:
    >>
    >> A nested class definition will be defined as an attribute of the class
    >>
    >> its defined within:
    >>
    >>
    >>
    >> >>> class Outer(object):

    >>
    >> ... foo = 'FOO'
    >>
    >> ... class Inner(object):
    >>
    >> ... bar = 'BAR'
    >>
    >> ...
    >>
    >> >>> Outer.Inner


    > Just one other doubt:
    >
    >> >>> Outer.Inner

    >>
    >> <class '__main__.Inner'>
    >>

    >
    > In the above output, I would have thought Python would print
    > __main__.Outer.Inner or Outer.Inner instead of __main__.Inner, since Inner
    > is an attribute of Outer?


    The Python developers seem to agree with you and have made the compiler
    smart enough to accomodate your expectations in Python 3.3:

    $ cat tmp.py
    class Outer:
    class Inner:
    pass

    print(Outer.Inner)
    $ python3.2 tmp.py
    <class '__main__.Inner'>
    $ python3.3 tmp.py
    <class '__main__.Outer.Inner'>
     
    Peter Otten, Apr 24, 2013
    #6
  7. vasudevram

    vasudevram Guest

    Interesting. Thank you.
     
    vasudevram, Apr 24, 2013
    #7
    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. Raffael Vogler
    Replies:
    8
    Views:
    1,165
    Chris Uppal
    Nov 30, 2003
  2. johny smith
    Replies:
    8
    Views:
    421
    Peter Koch Larsen
    Jul 2, 2004
  3. Harry Pehkonen
    Replies:
    8
    Views:
    322
    Christos TZOTZIOY Georgiou
    Sep 8, 2003
  4. prix prad

    #defining an array within another in C language

    prix prad, Mar 8, 2008, in forum: C Programming
    Replies:
    9
    Views:
    383
    Barry Schwarz
    Mar 11, 2008
  5. Gyoung-Yoon Noh
    Replies:
    1
    Views:
    100
    James Britt
    Dec 24, 2005
Loading...

Share This Page