views:

90

answers:

3

I have a class that needs access to urllib2, the trivial example for me is:

class foo(object):
    myStringHTML = urllib2.urlopen("http://www.google.com").read()

How should I structure my code to include urllib2? In general, I want to store foo in a utility module with a number of other classes, and be able to import foo by itself from the module:

from utilpackage import foo

Is the correct style to put the import inside the class? This seems strange to me, but it works....

class import_u2_in_foo(object):
    import urllib2
    myStringHtml = urllib2.urlopen("http://www.google.com").read()

Or should I move foo into another package so I always use

import foo
# then foo.py contains
import urllib2
class foo(object):
    myStringHtml = urllib2.urlopen("http://www.google.com").read()

How should I structure my code here to be the most pythonic :)?

+4  A: 

You should import it in the utilpackage module, but only export the class foo from it:

import urllib2

__all__ = ["foo"]

class foo(object):
    myStringHtml = urllib2.urlopen("http://www.google.com").read()

Then you can do

from utilpackage import foo

but not

from utilpackage import urllib2

That's best practice for from-imports in my opinion.

AndiDog
^ that, plus I would only import the `urlopen` if you don't need more from the package.
poke
So for __all__ accepts a list, ya? Then __all__ = ["foo","another_class","and_another_class"] if they existed would be ok?
mcpeterson
Yes, but the name is `__all__`. It defines what can be imported using a `from mymodule import ...` statement. When you do `from utilpackage import *`, only the stuff in the `__all__` list will be imported to your namespace. More details here: http://docs.python.org/tutorial/modules.html
AndiDog
A: 

Both class and import are normal Python instructions that have no magic attached (well, there are some things happening under the hood, but still they are just plain good Python instructions).

Python goes through your source code from top to bottom, executing every instruction on it its way - no matter if it's class instruction that creates new object for class, or import instruction that imports new module into current scope.

Moreover, because import instruction is as good instruction as any other, you can just put it inside class - you can think about classes in similar way as you think about .py files inside directories - and in the latter case you're probably used to that import can be put directly in main scope of .py file.

Writing all that, I'm not sure what you would like to achieve by adding this to your class:

   myStringHtml = urllib2.urlopen("http://www.google.com").read()

-- this instruction is parsed on class creation, and then all objects of the class are sharing the same myStringHtml value.

Regarding the question about best place to put import urllib2, I also don't quite understand the problem, but for me it seems most natural to do it in this way:

    import foo

    # then foo.py contains
    import urllib2

    class foo(object):
         myStringHtml = urllib2.urlopen("http://www.google.com").read()
Tomasz Zielinski
+1  A: 

My general rule of thumb is that if the import is used by many things within the file, I will put it at the very top. If it's only used by one single function or one single scope, I will place it closer to where it's used, say in the class or function.

However, this isn't a hard and fast rule, and I don't spend a lot of time thinking about the optimum place to put an import usually. Mostly, I put them at the top.

The two biggest reasons I like to have imports closer to where I use them is:

  • If the function imports the things it needs, then I can easily cut and paste that code out into another file, say for testing purposes or if it's boilerplate code like my "catch and syslog any exceptions that happen in this code" code.

  • If a function is infrequently used, or requires a module that isn't commonly installed for an infrequently used part, I don't have to import it when it's not used or require that users install a module they don't need.

Sean Reifschneider