where is best place for import statements?

Discussion in 'Python' started by Matthew Wilson, Oct 23, 2003.

  1. Hi-


    I'm writing a bunch of classes, several of which need functions and
    variables defined in the math module. In some instances, I'm going to
    import my module like this:

    import myshapes

    and then in others, I'll do:

    from myshapes import Circle

    or even:

    from myshapes import *

    How do I make sure that no matter how I import stuff from myshapes.py, I
    always also import the math module? Should I write all of my functions
    like so:

    def foo1():
    import math
    return math.pi

    def foo2():
    import math
    return 2*math.pi

    and all my classes like this:

    class Circle:
    def __init__(self,x, y, r):
    import math
    self.circumference = 2*r*math.pi

    Is this the way to solve the problem?


    Thanks for the help.
    Matthew Wilson, Oct 23, 2003
    #1
    1. Advertising

  2. Matthew Wilson

    John Roth Guest

    "Matthew Wilson" <> wrote in message
    news:...
    > Hi-
    >
    >
    > I'm writing a bunch of classes, several of which need functions and
    > variables defined in the math module. In some instances, I'm going to
    > import my module like this:
    >
    > import myshapes
    >
    > and then in others, I'll do:
    >
    > from myshapes import Circle
    >
    > or even:
    >
    > from myshapes import *
    >
    > How do I make sure that no matter how I import stuff from myshapes.py, I
    > always also import the math module? Should I write all of my functions
    > like so:
    >
    > def foo1():
    > import math
    > return math.pi
    >
    > def foo2():
    > import math
    > return 2*math.pi
    >
    > and all my classes like this:
    >
    > class Circle:
    > def __init__(self,x, y, r):
    > import math
    > self.circumference = 2*r*math.pi
    >
    > Is this the way to solve the problem?


    Your cure would probably solve the problem, but I
    consider it much worse than the disease of having
    to remember to stick the proper import statement
    at the front of the module. You'll get at most one
    error in each module where you forget to do that.

    In general, importing a module at other than the
    module level is something you do in very specialized
    circumstances: when you need either a dynamic or
    a conditional import.

    John Roth


    >
    > Thanks for the help.
    John Roth, Oct 23, 2003
    #2
    1. Advertising

  3. > Your cure would probably solve the problem, but I
    > consider it much worse than the disease of having
    > to remember to stick the proper import statement
    > at the front of the module. You'll get at most one
    > error in each module where you forget to do that.
    >
    > In general, importing a module at other than the
    > module level is something you do in very specialized
    > circumstances: when you need either a dynamic or
    > a conditional import.
    >
    > John Roth


    So, instead of scattering all those import statements throughout my
    file, I ought to just put them at the top of the file, right after the
    module description?

    And, if I decide to do something like

    from mymod import Circle

    Then it's up to me to remember to first do

    import math

    Is that right?
    Matthew Wilson, Oct 23, 2003
    #3
  4. Matthew Wilson

    John Roth Guest

    "Matthew Wilson" <> wrote in message
    news:...
    > > Your cure would probably solve the problem, but I
    > > consider it much worse than the disease of having
    > > to remember to stick the proper import statement
    > > at the front of the module. You'll get at most one
    > > error in each module where you forget to do that.
    > >
    > > In general, importing a module at other than the
    > > module level is something you do in very specialized
    > > circumstances: when you need either a dynamic or
    > > a conditional import.
    > >
    > > John Roth

    >
    > So, instead of scattering all those import statements throughout my
    > file, I ought to just put them at the top of the file, right after the
    > module description?
    >
    > And, if I decide to do something like
    >
    > from mymod import Circle
    >
    > Then it's up to me to remember to first do
    >
    > import math


    At that point, it doesn't matter. It only matters when you go to
    use it. However you organize the block of imports at the top
    of the file will usually work; if there's a lot, I find alphabetizing
    them sometimes helps, or sometimes putting the standard ones
    first.

    The one caveat to that is with modules that have circular
    dependencies, but that's a whole different set of problems than
    the one I think you're talking about.

    John Roth

    >
    > Is that right?
    >
    >
    John Roth, Oct 23, 2003
    #4
  5. Matthew Wilson

    Peter Otten Guest

    Matthew Wilson wrote:

    > How do I make sure that no matter how I import stuff from myshapes.py, I
    > always also import the math module? Should I write all of my functions


    Literal answer: put

    from math import *

    into myshapes.py, and access variables and functions like so:
    #test1.py
    import myshapes
    myshapes.pi
    myshapes.sin(alpha)
    myshapes.whatever
    ....
    #end test1.py

    However, I've got the impression that you think that in order to *use* your
    myshapes module, you have to import the math module.

    That is wrong, e. g.:

    #myshapes.py
    import math
    class Circle:
    def __init__(self, x, y, r):
    self.circumference = 2*r*math.pi
    #end myshapes py>

    You can use this in a script that does *not* import math:

    #test.py
    import myshapes
    veryRoundCircle = Circle(0, 0, 1.0)
    print veryRoundCircle.circumference
    #end test.py

    The general idea is to design modules as orthogonal as possible, i. e. it is
    good design for a module to provide its functionality without imposing
    restrictions on the client code. The usage of math.pi is only an
    implementation detail, that the user of myshape should not have to bother
    about. If you later add a Rectangle, you could provide a, say, turn(angle)
    method, again with the effect of *eliminating* the need for math.sin() etc.
    in client code.

    As an aside, think about making circumference in the above example a method,
    if you also store the radius in the instance. If you later change the
    radius, the circumference is thus updated automatically. General rule:
    avoid redundant data.

    Peter
    Peter Otten, Oct 23, 2003
    #5
  6. On Thu, 23 Oct 2003 14:52:07 +0000, Matthew Wilson wrote:
    > I'm writing a bunch of classes, several of which need functions and
    > variables defined in the math module. In some instances, I'm going to
    > import my module like this:
    >
    > import myshapes
    >
    > and then in others, I'll do:
    >
    > from myshapes import Circle


    You're best off avoiding importing things with from, except under
    certain specific circumstances. If you use it to import classes or
    variables from other modules then you run the risk of circular
    imports, which are horrid.

    It's generally considered better style to do this instead:

    import myshapes

    circle = myshapes.Circle()

    as (apart from avoiding the technical problems of "from") you then
    benefit from the contextual clues that the myshapes prefix gives
    you. It's a boon for others reading your code, or for yourself a few
    months down the line.

    > from myshapes import *


    Don't even go there, it's usually a bad habit. It makes for difficult
    to follow code, and can also reduce performance under some
    circumstances.

    > How do I make sure that no matter how I import stuff from myshapes.py, I
    > always also import the math module? Should I write all of my functions
    > like so:


    If myshapes imports math, then users of myshapes that don't need to
    refer to math themselves will never need to import it themselves. The
    convention is to group your import statements at the top of your
    module.

    See the Imports section of PEP 8 for more:

    http://www.python.org/peps/pep-0008.html

    Hope that helps.
    Graham Ashton, Oct 26, 2003
    #6
  7. On Thu, 23 Oct 2003 21:27:37 +0200, Peter Otten wrote:

    > Literal answer: put
    >
    > from math import *
    >
    > into myshapes.py, and access variables and functions like so:


    > import myshapes
    > myshapes.pi
    > myshapes.sin(alpha)


    Why on earth would you want to do that? If somebody wants to get the
    value of PI why would you want them to use anything other than math.pi
    directly? I realise you might be using this as an example of what you
    *could* do, but I don't think it's good practice.

    If I was reading code and saw myshapes.sin, and I new that math.sin
    existed (which I do as it's in the standard library), I would
    naturally assume that it was either an alternative implementation
    (which I wouldn't trust), or that it did something else entirely.
    Graham Ashton, Oct 26, 2003
    #7
  8. Matthew Wilson

    Peter Otten Guest

    Graham Ashton wrote:

    > On Thu, 23 Oct 2003 21:27:37 +0200, Peter Otten wrote:
    >
    >> Literal answer: put
    >>
    >> from math import *
    >>
    >> into myshapes.py, and access variables and functions like so:

    >
    >> import myshapes
    >> myshapes.pi
    >> myshapes.sin(alpha)

    >
    > Why on earth would you want to do that? If somebody wants to get the
    > value of PI why would you want them to use anything other than math.pi
    > directly? I realise you might be using this as an example of what you
    > *could* do, but I don't think it's good practice.


    Definitely not. I should have used a stronger disclaimer than "literal
    answer".

    I have a "builtins" module for the interpreter (and a few quick and dirty
    scripts) and always use it like that:

    from misc import *

    As the origin of the imported symbols is thus hidden, there is no potential
    for confusion that exceeds the general star import.

    > If I was reading code and saw myshapes.sin, and I new that math.sin
    > existed (which I do as it's in the standard library), I would
    > naturally assume that it was either an alternative implementation
    > (which I wouldn't trust), or that it did something else entirely.


    You are stressing the universality of sin() a bit much for my taste. Did you
    know that Python is shipped with two flavours of trigonometrical functions
    (float and complex)? I think Numeric has yet another one. So you could
    think of it this way: Let myshapes pick the appropriate sin (pun not
    intended but welcome) for me.

    Again, as I think I made clear in my previous post, if I were to implement
    myshapes, I would strive to hide sin() as an implementation detail.

    Peter
    Peter Otten, Oct 26, 2003
    #8
    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. Neil Zanella
    Replies:
    8
    Views:
    1,167
    mfmehdi
    Oct 20, 2006
  2. Dennis B. Hansen

    Schema import statements

    Dennis B. Hansen, Aug 4, 2003, in forum: XML
    Replies:
    1
    Views:
    476
    Mike Grayson
    Aug 11, 2003
  3. Harry George
    Replies:
    6
    Views:
    362
    Bart Nessux
    Feb 23, 2004
  4. Vince
    Replies:
    12
    Views:
    737
    Martin Gregorie
    Jan 21, 2008
  5. John Crichton
    Replies:
    6
    Views:
    253
    John Crichton
    Jul 12, 2010
Loading...

Share This Page