TL;DR of my finding is that module files may have a shared name, but the actually saved in the Python's sys.modules
is unique. Hence, it can be concluded that it is not possible for two or more modules to have the same name in Python.
To illustrate, we setup the following structures and explanation follows:
#add C:\superflous to the PYTHONPATH
C:\
superfluous\
mod.py
D:\
root\
mod.py
The question states:
if it's possible for my_module to import a function from other_module
where other_module.__name__ == my_module.__name__
For two modules to have the same __name__
, the module files name must be the same. But how to do it in Python context? We know we can't have two files with same name in a directory.
And, if we put in the ...sub\mod.py
the following line:
#...sub\mod.py
from mod import *
#or
import mod
...sub\mod.py
will just import itself and sys.modules
will include mod
as one of his dict
keys. We would like to import a module having the same as mod
, so let's import mod
from the C:superfluous\mod.py
. To do this we first put an __init__.py
inside sub
to turn it into a package directory and also to enable absolute import. In addition, let's add main.py
to the sub
directory. Our final structure:
D:\
root\
__init__.py
main.py
mod.py
We define main.py
and both of the mod.py
as follows:
#root\main.py
from . import mod
import sys
import types
print(f"{'mod:':<12}{{}}".format(sys.modules['mod']))
print(f"{'root.mod:':<12}{{}}".format(sys.modules['root.mod']))
print(f"{'-'*60}")
function_from_root_mod = (root_mod := sys.modules['root.mod'].__dict__).keys() - sys.modules['__main__'].__dict__
for i in function_from_root_mod:
if isinstance((root_mod_values := root_mod[i]), types.FunctionType) and root_mod_values.__module__ == 'root.mod':
print(f'func_name => {i} from modules "{root_mod_values.__module__}"')
#root\mod.py
from mod import *
def sub_mod_func(): pass
var_1 = 1
#C:\superfluous\mod.py
from collections import defaultdict
from itertools import permutations
def c_mod_func(): pass
We then execute main.py
through command prompt:
PS D:\> python -m root.main
the following is the output:
mod: <module 'mod' from 'C:\\superfluous\\mod.py'>
root.mod: <module 'root.mod' from 'D:\\root\\mod.py'>
------------------------------------------------------------
func_name => sub_mod_func from modules "root.mod"
Important findings:
- Relative import (
.
) in main.py
translated into root.mod
and becomes a key as in sys.modules['root.mod']
mod.py
in C:\superfluous
becomes sys.modules['mod']
Module files may have the same name, but the paths (directory that containing them, e.g., D:\root\mod.py
) provide uniqueness for the sys.modules
keys.