question about imports in a class

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Mon Dec 7 17:37:03 EST 2009


On Mon, 07 Dec 2009 16:53:46 -0500, J wrote:

> A little more education and playing around and I'm still not quite sure
> how to do this...
> 
> for the class i'm writing, I want to import os, sys and wmi globally for
> the class...

The best advice is Do Not Do It That Way. Just do your imports at the top 
level of the module:

import os

class MyClass():
    def findDMIDecode(self):
        for r,d,f in os.walk(args):
            ...

(Aside: it is traditional to write class names in Python using initial 
capitals.)


> if I put the import at the beginning of the class, it just dawned on me
> that perhaps I still have to explicitly call the function by class:
> 
> class myclass():
>     import os
>     def findDMIDecode(self):
>         for r,d,f in myclass.os.walk(args)
> 
> is that correct?

As Diez says, that works but it's not recommended. It's considered bad 
form.

It may help if you understand what import does: it does two basic 
functions: it loads a module, and it creates a name in the current 
namespace. So when you put:

import os

in the module, it loads os and creates a name 'os' that is now available 
to everything in the current module without qualification. But when you 
do this:

class MyClass():
    import os
    ...

the name 'os' is placed in the MyClass namespace, not the global 
namespace. So it is only available inside the MyClass namespace. That is 
precisely the same as if you had done this:

class MyClass():
    os = "something goes here"
    ...

Having done that, you have created a class attribute named 'os', so in 
your methods you have to do this:

class MyClass():
    import os
    def findDMIDecode(self):
        for r,d,f in self.os.walk(args):
            ...

This isn't exactly wrong, but it is terribly unusual and almost certainly 
unnecessary. The only reason I'd do it that way would be if:

(1) I needed to hide the os name from other classes or functions in the 
module; or 

(2) I wanted the ability to replace the os module in MyClass with a 
different module at runtime, without affecting other classes or functions.

E.g.:

inst = MyClass()
inst.os = my_fake_os_module
inst.findDMIDecode()  # calls my_fake_os_module.walk instead of os.walk

Both of these use-cases are very, very unusual. (I've never done needed 
to do this in real code.) Unless you have one of those rare cases, stick 
to the standard idiom of importing the module at the top level of the 
class. If you're not sure whether or not you need this, you almost 
certainly don't.


> How about if I have two classes in sysinfo.py and want to import os
> globally for BOTH classes to use? Same thing?

If one class inherits from the other, then self.os will work via the 
normal inheritance mechanism.

If they are independent classes, then you will need to import os in both 
of them, or just import it at the module level.


-- 
Steven



More information about the Python-list mailing list