embarrassing class question

Discussion in 'Python' started by Brendan, Oct 21, 2010.

  1. Brendan

    Brendan Guest

    Two modules:
    x.py:
    class x(object):
    pass

    y.py:
    from x import x
    class y(x):
    pass

    Now from the python command line:
    >>> import y
    >>> dir(y)

    ['__builtins__', '__doc__', '__file__', '__name__', '__package__',
    'x', 'y']

    I do not understand why class 'x' shows up here.
     
    Brendan, Oct 21, 2010
    #1
    1. Advertising

  2. Brendan

    Jonas H. Guest

    On 10/21/2010 08:09 PM, Brendan wrote:
    > Two modules:
    > x.py:
    > class x(object):
    > pass
    >
    > y.py:
    > from x import x
    > class y(x):
    > pass
    >
    > Now from the python command line:
    >>>> import y
    >>>> dir(y)

    > ['__builtins__', '__doc__', '__file__', '__name__', '__package__',
    > 'x', 'y']
    >
    > I do not understand why class 'x' shows up here.


    Because that's how `import` behaves. It imports *every* member of the
    module into the importing module's global namespace (except for
    attributes that start with an underscore).

    You can specify the attributes that shall be import with a star-import
    by settings __all__. In your case, you would add `__all__ = ['y']` to y.py.

    Jonas
     
    Jonas H., Oct 21, 2010
    #2
    1. Advertising

  3. Brendan

    Carl Banks Guest

    On Oct 21, 11:09 am, Brendan <> wrote:
    > Two modules:
    > x.py:
    > class x(object):
    >     pass
    >
    > y.py:
    > from x import x
    > class y(x):
    >     pass
    >
    > Now from the python command line:>>> import y
    > >>> dir(y)

    >
    > ['__builtins__', '__doc__', '__file__', '__name__', '__package__',
    > 'x', 'y']
    >
    > I do not understand why class 'x' shows up here.


    Because you imported it into the namespace, which is what the import
    statement does. dir() shows you what's in the namesace; therefore it
    lists x. dir() doesn't care, and can't know, if something was defined
    in a namespace, or merely imported.

    If it bothers you, you can put "del x" after the class y definition,
    but I recommend against doing that in general. If there's a reference
    to x inside a function that function will raise an exception if
    called, because it expects x to be inside the namespace.


    Carl Banks
     
    Carl Banks, Oct 21, 2010
    #3
  4. Brendan

    Brendan Guest

    On Oct 21, 3:47 pm, Carl Banks <> wrote:
    > On Oct 21, 11:09 am, Brendan <> wrote:
    >
    >
    >
    >
    >
    > > Two modules:
    > > x.py:
    > > class x(object):
    > >     pass

    >
    > > y.py:
    > > from x import x
    > > class y(x):
    > >     pass

    >
    > > Now from the python command line:>>> import y
    > > >>> dir(y)

    >
    > > ['__builtins__', '__doc__', '__file__', '__name__', '__package__',
    > > 'x', 'y']

    >
    > > I do not understand why class 'x' shows up here.

    >
    > Because you imported it into the namespace, which is what the import
    > statement does.  dir() shows you what's in the namesace; therefore it
    > lists x.  dir() doesn't care, and can't know, if something was defined
    > in a namespace, or merely imported.
    >
    > If it bothers you, you can put "del x" after the class y definition,
    > but I recommend against doing that in general.  If there's a reference
    > to x inside a function that function will raise an exception if
    > called, because it expects x to be inside the namespace.
    >
    > Carl Banks- Hide quoted text -
    >
    > - Show quoted text -


    So it must never make sense to put subclasses in separate modules?
     
    Brendan, Oct 21, 2010
    #4
  5. Brendan

    Ethan Furman Guest

    Jonas H. wrote:
    > On 10/21/2010 08:09 PM, Brendan wrote:
    >> Two modules:
    >> x.py:
    >> class x(object):
    >> pass
    >>
    >> y.py:
    >> from x import x
    >> class y(x):
    >> pass
    >>
    >> Now from the python command line:
    >>>>> import y
    >>>>> dir(y)

    >> ['__builtins__', '__doc__', '__file__', '__name__', '__package__',
    >> 'x', 'y']
    >>
    >> I do not understand why class 'x' shows up here.

    >
    > Because that's how `import` behaves. It imports *every* member of the
    > module into the importing module's global namespace (except for
    > attributes that start with an underscore).


    Um, no. (unless you do "from <whatever> import *" at the module level)

    What it does is add whatever you imported into the namespace where you
    imported it.

    Because y.py has "from x import x" the x class from x.py is added to the
    y.py namespace.

    ~Ethan~
     
    Ethan Furman, Oct 21, 2010
    #5
  6. Brendan

    Chris Rebert Guest

    On Thu, Oct 21, 2010 at 11:53 AM, Brendan <> wrote:
    > On Oct 21, 3:47 pm, Carl Banks <> wrote:
    >> On Oct 21, 11:09 am, Brendan <> wrote:
    >> > Two modules:
    >> > x.py:
    >> > class x(object):
    >> >     pass

    >>
    >> > y.py:
    >> > from x import x
    >> > class y(x):
    >> >     pass

    >>
    >> > Now from the python command line:>>> import y
    >> > >>> dir(y)

    >>
    >> > ['__builtins__', '__doc__', '__file__', '__name__', '__package__',
    >> > 'x', 'y']

    >>
    >> > I do not understand why class 'x' shows up here.

    >>
    >> Because you imported it into the namespace, which is what the import
    >> statement does.  dir() shows you what's in the namesace; therefore it
    >> lists x.  dir() doesn't care, and can't know, if something was defined
    >> in a namespace, or merely imported.
    >>
    >> If it bothers you, you can put "del x" after the class y definition,
    >> but I recommend against doing that in general.  If there's a reference
    >> to x inside a function that function will raise an exception if
    >> called, because it expects x to be inside the namespace.
    >>
    >> Carl Banks

    >
    > So it must never make sense to put subclasses in separate modules?


    Limiting yourself to one class per module is neither mandatory nor
    common in Python. Python is not Java.

    Cheers,
    Chris
     
    Chris Rebert, Oct 21, 2010
    #6
  7. Brendan

    Robert Kern Guest

    On 10/21/10 1:53 PM, Brendan wrote:
    > On Oct 21, 3:47 pm, Carl Banks<> wrote:
    >> On Oct 21, 11:09 am, Brendan<> wrote:
    >>
    >>
    >>
    >>
    >>
    >>> Two modules:
    >>> x.py:
    >>> class x(object):
    >>> pass

    >>
    >>> y.py:
    >>> from x import x
    >>> class y(x):
    >>> pass

    >>
    >>> Now from the python command line:>>> import y
    >>>>>> dir(y)

    >>
    >>> ['__builtins__', '__doc__', '__file__', '__name__', '__package__',
    >>> 'x', 'y']

    >>
    >>> I do not understand why class 'x' shows up here.

    >>
    >> Because you imported it into the namespace, which is what the import
    >> statement does. dir() shows you what's in the namesace; therefore it
    >> lists x. dir() doesn't care, and can't know, if something was defined
    >> in a namespace, or merely imported.
    >>
    >> If it bothers you, you can put "del x" after the class y definition,
    >> but I recommend against doing that in general. If there's a reference
    >> to x inside a function that function will raise an exception if
    >> called, because it expects x to be inside the namespace.
    >>
    >> Carl Banks

    >
    > So it must never make sense to put subclasses in separate modules?


    Of course it can make sense to put subclasses in separate modules, just for
    other reasons.

    --
    Robert Kern

    "I have come to believe that the whole world is an enigma, a harmless enigma
    that is made terrible by our own mad attempt to interpret it as though it had
    an underlying truth."
    -- Umberto Eco
     
    Robert Kern, Oct 21, 2010
    #7
  8. Brendan

    Ian Guest

    On Oct 21, 12:53 pm, Brendan <> wrote:
    > So it must never make sense to put subclasses in separate modules?


    It doesn't matter to Python whether the subclass is in the same module
    or imported. Do it whichever way makes the most sense to you from a
    code organization perspective.
     
    Ian, Oct 21, 2010
    #8
  9. Brendan

    Brendan Guest

    On Oct 21, 3:56 pm, Ethan Furman <> wrote:
    > Jonas H. wrote:
    > > On 10/21/2010 08:09 PM, Brendan wrote:
    > >> Two modules:
    > >> x.py:
    > >> class x(object):
    > >>      pass

    >
    > >> y.py:
    > >> from x import x
    > >> class y(x):
    > >>      pass

    >
    > >> Now from the python command line:
    > >>>>> import y
    > >>>>> dir(y)
    > >> ['__builtins__', '__doc__', '__file__', '__name__', '__package__',
    > >> 'x', 'y']

    >
    > >> I do not understand why class 'x' shows up here.

    >
    > > Because that's how `import` behaves. It imports *every* member of the
    > > module into the importing module's global namespace (except for
    > > attributes that start with an underscore).

    >
    > Um, no.  (unless you do "from <whatever> import *" at the module level)
    >
    > What it does is add whatever you imported into the namespace where you
    > imported it.
    >
    > Because y.py has "from x import x" the x class from x.py is added to the
    > y.py namespace.
    >
    > ~Ethan~- Hide quoted text -
    >
    > - Show quoted text -


    So what is usually done to prevent this? (In my case not wanting class
    x added to the y.py namespace)
    It seems sloppy.
     
    Brendan, Oct 21, 2010
    #9
  10. Brendan

    Carl Banks Guest

    On Oct 21, 11:53 am, Brendan <> wrote:
    > On Oct 21, 3:47 pm, Carl Banks <> wrote:
    > > On Oct 21, 11:09 am, Brendan <> wrote:

    >
    > > > Two modules:
    > > > x.py:
    > > > class x(object):
    > > >     pass

    >
    > > > y.py:
    > > > from x import x
    > > > class y(x):
    > > >     pass

    >
    > > > Now from the python command line:>>> import y
    > > > >>> dir(y)

    >
    > > > ['__builtins__', '__doc__', '__file__', '__name__', '__package__',
    > > > 'x', 'y']

    >
    > > > I do not understand why class 'x' shows up here.

    >
    > > Because you imported it into the namespace, which is what the import
    > > statement does.  dir() shows you what's in the namesace; therefore it
    > > lists x.  dir() doesn't care, and can't know, if something was defined
    > > in a namespace, or merely imported.

    >
    > > If it bothers you, you can put "del x" after the class y definition,
    > > but I recommend against doing that in general.  If there's a reference
    > > to x inside a function that function will raise an exception if
    > > called, because it expects x to be inside the namespace.

    >
    > So it must never make sense to put subclasses in separate modules?


    Putting a subclass in the same module simply because you don't want it
    to appear in some other module's namespace is not a good idea, IMO.
    Sometimes it makes sense to put the subclass in another module, it
    depends on the organization of the project.

    I'm not sure how familiar you are with Python's object and namespace
    systems. I assumed you were using dir() to see what objects were
    defined in a module, and were disappointed to see x in the listing
    also, but maybe you're under the impression that there is a lot of
    duplicated data? Not really: a namespace contains references
    (pointers) and so takes up a minimal amount of space, not worth
    worrying about.


    Carl Banks
     
    Carl Banks, Oct 21, 2010
    #10
  11. Brendan

    Robert Kern Guest

    On 10/21/10 2:12 PM, Brendan wrote:
    > On Oct 21, 3:56 pm, Ethan Furman<> wrote:
    >> Jonas H. wrote:
    >>> On 10/21/2010 08:09 PM, Brendan wrote:
    >>>> Two modules:
    >>>> x.py:
    >>>> class x(object):
    >>>> pass

    >>
    >>>> y.py:
    >>>> from x import x
    >>>> class y(x):
    >>>> pass

    >>
    >>>> Now from the python command line:
    >>>>>>> import y
    >>>>>>> dir(y)
    >>>> ['__builtins__', '__doc__', '__file__', '__name__', '__package__',
    >>>> 'x', 'y']

    >>
    >>>> I do not understand why class 'x' shows up here.

    >>
    >>> Because that's how `import` behaves. It imports *every* member of the
    >>> module into the importing module's global namespace (except for
    >>> attributes that start with an underscore).

    >>
    >> Um, no. (unless you do "from<whatever> import *" at the module level)
    >>
    >> What it does is add whatever you imported into the namespace where you
    >> imported it.
    >>
    >> Because y.py has "from x import x" the x class from x.py is added to the
    >> y.py namespace.
    >>
    >> ~Ethan~- Hide quoted text -
    >>
    >> - Show quoted text -

    >
    > So what is usually done to prevent this? (In my case not wanting class
    > x added to the y.py namespace)
    > It seems sloppy.


    You can explicitly delete it at the end of the file if you never reference it
    from one of your methods.

    Mostly though, it just doesn't matter much. I recommend leaving it alone. If you
    want a nice, clean namespace for people to use, make a module (e.g. api.py) that
    doesn't define any classes or functions but just imports them from their
    defining modules.

    --
    Robert Kern

    "I have come to believe that the whole world is an enigma, a harmless enigma
    that is made terrible by our own mad attempt to interpret it as though it had
    an underlying truth."
    -- Umberto Eco
     
    Robert Kern, Oct 21, 2010
    #11
  12. On Thu, 21 Oct 2010 12:12:34 -0700, Brendan wrote:

    >> Because y.py has "from x import x" the x class from x.py is added to
    >> the y.py namespace.
    >>
    >> ~Ethan~- Hide quoted text -
    >>
    >> - Show quoted text -

    >
    > So what is usually done to prevent this? (In my case not wanting class x
    > added to the y.py namespace)
    > It seems sloppy.



    (1) Don't import it in the first place.

    (2) Import it with a different name, possibly private:

    from module import x as _x

    (3) Delete it when you're done:

    from module import x
    class Y(x):
    pass
    del x

    (4) Don't be so fussy and just accept that importing adds names to the
    namespace, as does any other assignment or class or function definition.




    --
    Steven
     
    Steven D'Aprano, Oct 22, 2010
    #12
  13. Brendan

    Brendan Guest

    On Oct 22, 5:02 am, Steven D'Aprano <st...@REMOVE-THIS-
    cybersource.com.au> wrote:
    > On Thu, 21 Oct 2010 12:12:34 -0700, Brendan wrote:
    > >> Because y.py has "from x import x" the x class from x.py is added to
    > >> the y.py namespace.

    >
    > >> ~Ethan~- Hide quoted text -

    >
    > >> - Show quoted text -

    >
    > > So what is usually done to prevent this? (In my case not wanting class x
    > > added to the y.py namespace)
    > > It seems sloppy.

    >
    > (1) Don't import it in the first place.
    >
    > (2) Import it with a different name, possibly private:
    >
    > from module import x as _x
    >
    > (3) Delete it when you're done:
    >
    > from module import x
    > class Y(x):
    >     pass
    > del x
    >
    > (4) Don't be so fussy and just accept that importing adds names to the
    > namespace, as does any other assignment or class or function definition.
    >
    > --
    > Steven


    I'll take (2) and pass on (4)
    Thanks
     
    Brendan, Oct 22, 2010
    #13
  14. Brendan

    Dave Angel Guest

    Re: Re: embarrassing class question

    On 2:59 PM, Brendan wrote:
    > On Oct 21, 3:56 pm, Ethan Furman<> wrote:
    >> <snip>
    >> Because y.py has "from x import x" the x class from x.py is added to the
    >> y.py namespace.
    >>
    >> ~Ethan~- Hide quoted text -
    >>
    >> - Show quoted text -

    > So what is usually done to prevent this? (In my case not wanting class
    > x added to the y.py namespace)
    > It seems sloppy.
    >

    Since you make the common mistake of using the same name for the module
    as you do for the class, it's hard to demonstrate. But if you used Pep8
    naming conventions, the classes would be capitalized.

    Instead of using

    from x import X

    try using

    import x

    class Y(x.X):
    pass

    Now, you still have a symbol x in your namespace, but it's just the
    module, which is perfectly public. So you could access a dozen classes
    within x, but only the module itself would be visible to others.

    As someone else pointed out, you could also delete the module reference
    when you're done with it.

    import x

    class Y(x.X):
    pass

    del x


    DaveA
     
    Dave Angel, Oct 22, 2010
    #14
  15. Brendan

    Brendan Guest

    On Oct 22, 9:16 am, Dave Angel <> wrote:
    > On 2:59 PM, Brendan wrote:> On Oct 21, 3:56 pm, Ethan Furman<>  wrote:
    > >> <snip>
    > >> Because y.py has "from x import x" the x class from x.py is added to the
    > >> y.py namespace.

    >
    > >> ~Ethan~- Hide quoted text -

    >
    > >> - Show quoted text -

    > > So what is usually done to prevent this? (In my case not wanting class
    > > x added to the y.py namespace)
    > > It seems sloppy.

    >
    > Since you make the common mistake of using the same name for the module
    > as you do for the class, it's hard to demonstrate.  But if you used Pep8
    > naming conventions, the classes would be capitalized.
    >
    > Instead of using
    >
    > from x import X
    >
    > try using
    >
    > import x
    >
    > class Y(x.X):
    >      pass
    >
    > Now, you still have a symbol x in your namespace, but it's just the
    > module, which is perfectly public.  So you could access a dozen classes
    > within x, but only the module itself would be visible to others.
    >
    > As someone else pointed out, you could also delete the module reference
    > when you're done with it.
    >
    > import x
    >
    > class Y(x.X):
    >      pass
    >
    > del x
    >
    > DaveA


    x.py
    class X(object):
    pass

    y.py
    import x
    class Y(x.X):
    pass

    z.py
    import x
    import y
    class ZX(x.X):
    pass
    class ZY(y.Y):
    pass

    w.py
    import x
    import y
    import z
    class WX(x.X):
    pass
    class WY(y.Y):
    pass
    class WZX(z.ZX):
    pass
    class WZY(z.ZY):
    pass

    >>> import x, y, z, w
    >>> dir(x)

    ['X', '__builtins__', '__doc__', '__file__', '__name__',
    '__package__']
    >>> dir(y)

    ['Y', '__builtins__', '__doc__', '__file__', '__name__',
    '__package__', 'x']
    >>> dir(z)

    ['ZX', 'ZY', '__builtins__', '__doc__', '__file__', '__name__',
    '__package__', 'x', 'y']
    >>> dir(w)

    ['WX', 'WY', 'WZX', 'WZY', '__builtins__', '__doc__', '__file__',
    '__name__', '__package__', 'x', 'y', 'z']
     
    Brendan, Oct 22, 2010
    #15
  16. On Fri, 22 Oct 2010 07:49:39 -0700 (PDT), Brendan wrote:
    [snip]
    > x.py
    > class X(object):
    > pass
    >
    > y.py
    > import x
    > class Y(x.X):
    > pass
    >
    > z.py
    > import x
    > import y
    > class ZX(x.X):
    > pass
    > class ZY(y.Y):
    > pass
    >
    > w.py
    > import x
    > import y
    > import z
    > class WX(x.X):
    > pass
    > class WY(y.Y):
    > pass
    > class WZX(z.ZX):
    > pass
    > class WZY(z.ZY):
    > pass
    >
    >>>> import x, y, z, w
    >>>> dir(x)

    > ['X', '__builtins__', '__doc__', '__file__', '__name__',
    > '__package__']
    >>>> dir(y)

    > ['Y', '__builtins__', '__doc__', '__file__', '__name__',
    > '__package__', 'x']
    >>>> dir(z)

    > ['ZX', 'ZY', '__builtins__', '__doc__', '__file__', '__name__',
    > '__package__', 'x', 'y']
    >>>> dir(w)

    > ['WX', 'WY', 'WZX', 'WZY', '__builtins__', '__doc__', '__file__',
    > '__name__', '__package__', 'x', 'y', 'z']


    I apologize for being dense, but I don't understand what bothers
    you about this behavior. Yes, module w imports x, and therefore
    w.x exists. Is that bad?


    --
    To email me, substitute nowhere->spamcop, invalid->net.
     
    Peter Pearson, Oct 22, 2010
    #16
  17. Brendan

    Brendan Guest

    On Oct 22, 2:21 pm, Peter Pearson <> wrote:
    > On Fri, 22 Oct 2010 07:49:39 -0700 (PDT), Brendan wrote:
    >
    > [snip]
    >
    >
    >
    >
    >
    > > x.py
    > > class X(object):
    > >     pass

    >
    > > y.py
    > > import x
    > > class Y(x.X):
    > >     pass

    >
    > > z.py
    > > import x
    > > import y
    > > class ZX(x.X):
    > >     pass
    > > class ZY(y.Y):
    > >     pass

    >
    > > w.py
    > > import x
    > > import y
    > > import z
    > > class WX(x.X):
    > >     pass
    > > class WY(y.Y):
    > >     pass
    > > class WZX(z.ZX):
    > >     pass
    > > class WZY(z.ZY):
    > >     pass

    >
    > >>>> import x, y, z, w
    > >>>> dir(x)

    > > ['X', '__builtins__', '__doc__', '__file__', '__name__',
    > > '__package__']
    > >>>> dir(y)

    > > ['Y', '__builtins__', '__doc__', '__file__', '__name__',
    > > '__package__', 'x']
    > >>>> dir(z)

    > > ['ZX', 'ZY', '__builtins__', '__doc__', '__file__', '__name__',
    > > '__package__', 'x', 'y']
    > >>>> dir(w)

    > > ['WX', 'WY', 'WZX', 'WZY', '__builtins__', '__doc__', '__file__',
    > > '__name__', '__package__', 'x', 'y', 'z']

    >
    > I apologize for being dense, but I don't understand what bothers
    > you about this behavior.  Yes, module w imports x, and therefore
    > w.x exists.  Is that bad?
    >
    > --
    > To email me, substitute nowhere->spamcop, invalid->net.- Hide quoted text -
    >
    > - Show quoted text -


    No worries. I am the one who is dense. What bothers me is that I have
    not noticed this before when importing other Python modules. I use
    Python sporadically, and frequently use the dir command to learn or
    remind myself of class methods. Python examples/tutorials on classes
    always show everything(classes and subclasses) in the same module.
     
    Brendan, Oct 25, 2010
    #17
  18. Brendan wrote:
    > I use
    > Python sporadically, and frequently use the dir command to learn or
    > remind myself of class methods.


    You can clean up dir() by defining __all__ as a list of
    names that you want to officially export. Other names will
    still be there, but they won't show up in the dir() listing.

    --
    Greg
     
    Gregory Ewing, Oct 29, 2010
    #18
  19. Brendan

    Paul Rudin Guest

    Gregory Ewing <> writes:

    > Brendan wrote:
    >> I use
    >> Python sporadically, and frequently use the dir command to learn or
    >> remind myself of class methods.

    >
    > You can clean up dir() by defining __all__ as a list of
    > names that you want to officially export. Other names will
    > still be there, but they won't show up in the dir() listing.


    I'm not sure that's necessarily a good idea... when you're trying to figure
    out why something behaves in a certain way you want to check for the
    presence of methods with special names.
     
    Paul Rudin, Oct 29, 2010
    #19
  20. In message <>, Peter Pearson wrote:

    > Yes, module w imports x, and therefore w.x exists. Is that bad?


    No-one seems to have come out and said this yet (unless it was in one of
    those messages that no longer seem to be accessible on my ISP’s news
    server): Python has no provision for visibility control. That’s it. No
    public/private/protected or anything like that. Everything defined directly
    within a module or class is visible outside it using dir(module_or_class).
     
    Lawrence D'Oliveiro, Oct 30, 2010
    #20
    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,902
    Thomas Weidenfeller
    Oct 12, 2005
  2. luser-ex-troll

    embarrassing spaghetti code needs stylistic advice

    luser-ex-troll, Mar 20, 2009, in forum: C Programming
    Replies:
    72
    Views:
    1,661
    JosephKK
    Mar 31, 2009
  3. T_P
    Replies:
    9
    Views:
    1,113
    Jerry Coffin
    Sep 12, 2009
  4. Aaron Fude

    Embarrassing regex question

    Aaron Fude, Jun 20, 2010, in forum: Java
    Replies:
    5
    Views:
    286
    Daniel Pitts
    Jun 21, 2010
  5. Christopher Rose

    Embarrassing question -

    Christopher Rose, Jul 18, 2006, in forum: Ruby
    Replies:
    3
    Views:
    118
Loading...

Share This Page