[Tutor] how import a module upon instantiation of a class?

Steven D'Aprano steve at pearwood.info
Mon Sep 1 18:24:17 CEST 2014


On Mon, Sep 01, 2014 at 04:55:09PM +0100, Alan Gauld wrote:

> And co ing back to Albert's original request this little insight made me 
> try something and it seems to work...
> 
> You can assign the name inside the class, thus providing the class level 
> import that Albert wanted:
> 
> >>> class C:
> ...   def __init__(self):
> ...     import sys
> ...     self.__sys = sys
> ...   def printSys(self):
> ...     print self.__sys.path
> ...
> >>> c = C()
> >>> sys
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> NameError: name 'sys' is not defined
> >>> c.__sys
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> AttributeError: C instance has no attribute '__sys'

That's just Python's regular old "name mangling" in progress. If you 
create a method or attribute with a name starting with two underscores, 
but not ending with two underscores, the Python compiler mangles 
references to it. This is quite lame protection from accidental name 
clashes, but it can easily be over-come. Try this:

c._C__sys

Python simply stuffs a single underscore and the name of the class in 
front of the double leading underscore attribute name. It's enough to 
prevent 99% of accidental name clashes, but anyone who wants to can 
defeat it.


> >>> c.printSys()
> ['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', ...
> 
> So now you have a module imported inside a class such that it
> is only visible inside objects of that class.

Not quite invisible. More like standing in the corner covered with a 
white sheet. So long as nobody peeks under the sheet, nobody can see it.


-- 
Steven


More information about the Tutor mailing list