Simplifying imports?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • chapolim-colorado@bol.com.br

    #1

    Simplifying imports?

    I like to keep my classes each in a separate file with the same name of
    the class. The problem with that is that I end up with multiple imports
    in the beginning of each file, like this:

    from foo.Bar import Bar
    from foo.Blah import Blah
    from foo.Zzz import Zzz

    What I'd like to do would be to replace it all by a single line:

    from foo.* import *

    Of course, that doesn't work, but is there a way to do something like
    that?

    Chapolim

  • Neal  Norwitz

    #2
    Re: Simplifying imports?

    chapolim-colorado@bol.co m.br wrote:[color=blue]
    > I like to keep my classes each in a separate file with the same name of
    > the class. The problem with that is that I end up with multiple imports
    > in the beginning of each file, like this:
    >
    > from foo.Bar import Bar
    > from foo.Blah import Blah
    > from foo.Zzz import Zzz[/color]

    Must ... resist ... temptation ... to ... complain ... about ... J...
    [color=blue]
    > What I'd like to do would be to replace it all by a single line:
    >
    > from foo.* import *
    >
    > Of course, that doesn't work, but is there a way to do something like
    > that?[/color]

    In foo there is a file __init__.py, right? If you have 3 class files
    in foo: bar.py, baz.py, and bax.py, you're __init__.py could contain:

    # __init__.py
    from foo.bar import Bar
    from foo.baz import Baz
    from foo.bax import Bax
    # end of __init__.py

    Then, voila:
    [color=blue][color=green][color=darkred]
    >>> import foo
    >>> dir(foo)[/color][/color][/color]
    ['Bar', 'Bax', 'Baz', '__builtins__', '__doc__', '__file__',
    '__name__', '__path__', 'bar', 'bax', 'baz']

    You could write code in __init__.py to import all the files in foo/ if
    you wanted. That way you wouldn't have to explicitly list each file.
    (Hint: see os.listdir() and __import__().)

    HTH,
    n

    PS. I don't really like this approach. It seems too implicit
    (magical).

    Comment

    • Terry Hancock

      #3
      Re: Simplifying imports?

      On Monday 12 September 2005 10:09 pm, chapolim-colorado@bol.co m.br wrote:[color=blue]
      > I like to keep my classes each in a separate file with the same name of
      > the class. The problem with that is that I end up with multiple imports
      > in the beginning of each file, like this:
      >
      > from foo.Bar import Bar
      > from foo.Blah import Blah
      > from foo.Zzz import Zzz
      >
      > What I'd like to do would be to replace it all by a single line:
      >
      > from foo.* import *
      >
      > Of course, that doesn't work, but is there a way to do something like
      > that?[/color]

      Apparently "foo" is already a package defined using __init__.py,
      so you know about that part already.

      Just change its contents to read:

      from Bar import Bar
      from Blah import Blah
      from Zzz import Zzz

      Then whenever you need to use these classes, you only need:

      from foo import Bar, Blah, Zzz

      or

      from foo import *

      Cheers,
      Terry

      --
      Terry Hancock ( hancock at anansispacework s.com )
      Anansi Spaceworks http://www.anansispaceworks.com

      Comment

      • Reinhold Birkenfeld

        #4
        Re: Simplifying imports?

        Terry Hancock wrote:[color=blue]
        > On Monday 12 September 2005 10:09 pm, chapolim-colorado@bol.co m.br wrote:[color=green]
        >> I like to keep my classes each in a separate file with the same name of
        >> the class. The problem with that is that I end up with multiple imports
        >> in the beginning of each file, like this:
        >>
        >> from foo.Bar import Bar
        >> from foo.Blah import Blah
        >> from foo.Zzz import Zzz
        >>
        >> What I'd like to do would be to replace it all by a single line:
        >>
        >> from foo.* import *
        >>
        >> Of course, that doesn't work, but is there a way to do something like
        >> that?[/color]
        >
        > Apparently "foo" is already a package defined using __init__.py,
        > so you know about that part already.
        >
        > Just change its contents to read:
        >
        > from Bar import Bar
        > from Blah import Blah
        > from Zzz import Zzz
        >
        > Then whenever you need to use these classes, you only need:
        >
        > from foo import Bar, Blah, Zzz
        >
        > or
        >
        > from foo import *[/color]

        Or, if the Bar, Blah and Zzz classes are small enough, there's no need to
        put each of them in separate modules. Just put them in foo.py.

        Concise structuring of classes and modules is not easy. Structure too much,
        and you will not see the wood for the trees. Structure too little, and you
        won't find things anymore. IMO, the Twisted project is an example of
        excellent Python structuring.

        Reinhold

        Comment

        • bruno modulix

          #5
          Re: Simplifying imports?

          chapolim-colorado@bol.co m.br wrote:[color=blue]
          > I like to keep my classes each in a separate file with the same name of
          > the class.[/color]

          Let me guess: you have a C++ or Java background ?-)

          --
          bruno desthuilliers
          python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
          p in 'onurb@xiludom. gro'.split('@')])"

          Comment

          • chapolim-colorado@bol.com.br

            #6
            Re: Simplifying imports?

            bruno modulix wrote:[color=blue]
            >Let me guess: you have a C++ or Java background ?[/color]

            You're right, I come from Java :). I'm still learning the Pythonic
            approach. Thank you guys

            Chapolim

            Comment

            • George Sakkis

              #7
              Re: Simplifying imports?

              "Terry Hancock" <hancock@anansi spaceworks.com> wrote:
              [color=blue]
              > On Monday 12 September 2005 10:09 pm, chapolim-colorado@bol.co m.br wrote:[color=green]
              > > I like to keep my classes each in a separate file with the same name of
              > > the class. The problem with that is that I end up with multiple imports
              > > in the beginning of each file, like this:
              > >
              > > from foo.Bar import Bar
              > > from foo.Blah import Blah
              > > from foo.Zzz import Zzz
              > >
              > > What I'd like to do would be to replace it all by a single line:
              > >
              > > from foo.* import *
              > >
              > > Of course, that doesn't work, but is there a way to do something like
              > > that?[/color]
              >
              > Apparently "foo" is already a package defined using __init__.py,
              > so you know about that part already.
              >
              > Just change its contents to read:
              >
              > from Bar import Bar
              > from Blah import Blah
              > from Zzz import Zzz[/color]

              If you do this often or have lots of classes you want to import this
              way, you could automate it:

              #======== Foo.py =============== =============== ======
              class Foo(object):
              pass

              #======== Bar.py =============== =============== ======
              class Bar(object):
              pass

              #======== test.py =============== =============== ======
              from autoimport import autoimport
              autoimport("Foo ","Bar")

              if __name__ == '__main__':
              print Foo
              print Bar

              # output:
              # <class 'Foo.Foo'>
              # <class 'Bar.Bar>

              #======== autoimport.py =============== =============== ======
              import sys

              def autoimport(*mod ulenames):
              '''
              Perform the equivalent of "from XXX import XXX" for every
              module XXX in modulenames. In case of packaged modules, it is
              equivalent to "from XXX.YYY.ZZZ import ZZZ"
              '''
              caller_frame = sys._getframe(1 )
              caller_locals = caller_frame.f_ locals
              # import every module XXX and add the XXX.XXX object
              # to the caller's locals
              for name in modulenames:
              # in case of packaged modules A.B.C, make sure to import C
              module = __import__(name , caller_frame.f_ globals,
              caller_locals, [name])
              # extract 'C' from 'A.B.C'
              attribute = name[name.rfind('.') +1:]
              if hasattr(module, attribute):
              caller_locals[attribute] = getattr(module, attribute)

              #============== =============== =============== ======

              Or even better, forget about the braindead java restriction of one
              class per file and organize your code as it makes more sense to you.

              HTH,
              George

              Comment

              • Steven D'Aprano

                #8
                Re: Simplifying imports?

                On Mon, 12 Sep 2005 20:09:31 -0700, chapolim-colorado wrote:
                [color=blue]
                > I like to keep my classes each in a separate file with the same name of
                > the class. The problem with that is that I end up with multiple imports
                > in the beginning of each file, like this:
                >
                > from foo.Bar import Bar
                > from foo.Blah import Blah
                > from foo.Zzz import Zzz
                >
                > What I'd like to do would be to replace it all by a single line:
                >
                > from foo.* import *
                >
                > Of course, that doesn't work, but is there a way to do something like
                > that?[/color]

                "Doctor, it hurts when I do this."

                "Then don't do that."

                If putting one class per file causes you pain, then don't put one class
                per file. The idea of packages is to make things easier for you, not
                harder -- if you are having to fight the import mechanism, then perhaps
                you need to rethink your design.

                eg if you have a good reason for requiring one class per file, then one
                possible work around would be to define a single "header" module
                containing all those "from foo.Bar import Bar" statements, and then in
                your actual module(s) call "from header import *". Watch out for circular
                imports though.


                --
                Steven.

                Comment

                • Terry Hancock

                  #9
                  Re: Simplifying imports?

                  On Tuesday 13 September 2005 12:46 pm, George Sakkis wrote:[color=blue]
                  > "Terry Hancock" <hancock@anansi spaceworks.com> wrote:[color=green]
                  > > On Monday 12 September 2005 10:09 pm, chapolim-colorado@bol.co m.br wrote:[color=darkred]
                  > > > I like to keep my classes each in a separate file with the same name of
                  > > > the class.[/color]
                  > > Apparently "foo" is already a package defined using __init__.py,
                  > > so you know about that part already.
                  > >
                  > > Just change its contents to read:
                  > >
                  > > from Bar import Bar
                  > > from Blah import Blah
                  > > from Zzz import Zzz[/color]
                  >
                  > If you do this often or have lots of classes you want to import this
                  > way, you could automate it:[/color]

                  (nice)
                  [color=blue]
                  > [...]
                  > Or even better, forget about the braindead java restriction of one
                  > class per file and organize your code as it makes more sense to you.[/color]

                  While this is good sound Python advice, there are good Human-readability
                  reasons for keeping a small number of classes per module. Python classes
                  certainly may not tend to blossum into the verbosity of their Java
                  counterparts, but I've still seen some pretty chunky classes (e.g. in
                  the Zope sources). So, the __init__.py approach and packaging is
                  still a good idea.

                  I particularly like the ability of __init__.py to craft the interface
                  layout of the module, independently of the file-structure that you
                  choose, as the best layout for the user may not be the best layout
                  for the developer.

                  I personally wouldn't favor automating this process unless you are
                  actually working with some kind of "plugin" design pattern. It's nicer
                  to have the fine control over the interface and be able to pick and
                  choose how things should be laid out. And the __init__.py code then
                  serves as a map for the developer to figure out where things are stored
                  (yes, they could also use grep, but every little bit helps).


                  --
                  Terry Hancock ( hancock at anansispacework s.com )
                  Anansi Spaceworks http://www.anansispaceworks.com

                  Comment

                  • George Sakkis

                    #10
                    Re: Simplifying imports?

                    "Terry Hancock" <hancock@anansi spaceworks.com> wrote:
                    [color=blue]
                    > On Tuesday 13 September 2005 12:46 pm, George Sakkis wrote:[color=green]
                    > > Or even better, forget about the braindead java restriction of one
                    > > class per file and organize your code as it makes more sense to you.[/color]
                    >
                    > While this is good sound Python advice, there are good Human-readability
                    > reasons for keeping a small number of classes per module. Python classes
                    > certainly may not tend to blossum into the verbosity of their Java
                    > counterparts, but I've still seen some pretty chunky classes (e.g. in
                    > the Zope sources). So, the __init__.py approach and packaging is
                    > still a good idea.[/color]

                    I agree, and that's what I had in mind with "as it makes more sense to
                    you". Big fat classes _are_ a good reason to keep them in separate
                    files, if nothing else, for readability reasons. What's braindead is
                    that java imposes a rule for what should be at best a good style
                    guideline.

                    George

                    Comment

                    Working...