Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

imported modules becomes None when replacing current module in sys.modules using a class object

an unpopular but "supported" python hack (see Guido: https://mail.python.org/pipermail/python-ideas/2012-May/014969.html) that enables __getattr__ usage on module attributes involves the following:

import os, sys

class MyClass(object):

    def check_os(self):
        print os

sys.modules[__name__] = MyClass()

On import, this the imported module becomes a class instance:

>>> import myModule
>>> myModule
<myModule.MyClass object at 0xf76def2c>

However, in Python-2.7, all other imported modules within the original module is set to None.

>>> repro.check_os()
None

In Python-3.4, everything works:

>>> repro.check_os()
<module 'os' from '/python/3.4.1/lib/python3.4/os.py'>

This feels like something to do with Imported modules become None when running a function, but, anyone knows why this happens internally?

It seems that if you store the original module (without fully replacing it in Python-2) then everything continues to work:

sys.modules[__name__+'_bak'] = sys.modules[__name__]      
like image 353
Bubai Avatar asked Mar 17 '15 18:03

Bubai


People also ask

What happens when you import a module Python?

When a module is first imported, Python searches for the module and if found, it creates a module object 1, initializing it. If the named module cannot be found, a ModuleNotFoundError is raised. Python implements various strategies to search for the named module when the import machinery is invoked.

Can a module import another module?

Such a file is called a module; definitions from a module can be imported into other modules or into the main module (the collection of variables that you have access to in a script executed at the top level and in calculator mode).

What is import * in Python?

Python code in one module gains access to the code in another module by the process of importing it. The import statement is the most common way of invoking the import machinery, but it is not the only way. Functions such as importlib.

Can you manually import a module in Python?

append() Function. This is the easiest way to import a Python module by adding the module path to the path variable. The path variable contains the directories Python interpreter looks in for finding modules that were imported in the source files.


1 Answers

The problem you are running in to is that in Pythons prior to 3.4 when a module is destroyed (as yours is because you replace it with a class and there are no further references to it), the items in that module's __dict__ are forcibly set to None.

The workaround, if you need to support Pythons prior to 3.4, is have an import statement in the class that will replace the module:

class MyClass(object):

    import os

    def check_os(self):
        print(os)

For more info, see this answer about interpreter shutdown.

like image 132
Ethan Furman Avatar answered Nov 15 '22 19:11

Ethan Furman