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