This is my project structure:
a
├── b.py
└── __init__.py
File b.py
is empty.
File __init__.py
is one line:
b = 'this is a str'
Then the following program gives inconsistent result of a.b
:
import a
print(a.b) # str
import a.b
print(a.b) # module
What is the best way of detecting this kind of name conflict between a variable and a filename?
print(a.b)
"I'd like to point out that while the results may be different, in fact, Python isn't doing anything inconsistent here. Without going into too much detail, here's what's happening at each step in your program.
import a
Python searches the directories on sys.path
until it finds one of these: a file called "a.py", or a directory called "a" containing a file called __init__.py
. Python then imports your package. Notably, Python does not look through package "a" and automatically import all ".py" files from it (this saves memory and time).
print (a.b)
Python looks up the attribute b
of a
, which it finds in a
's __dict__
attribute. The value of b
is 'this is a string'
, which is printed.
import a.b
Python imports your module. With this statement, the value corresponding to key b
within a
's __dict__
becomes the module object a.b
.
print (a.b)
Python looks up the attribute b
. The value of b
is the module object a.b
, which is printed.
You could write a script to list the names of all the modules in your package, as well as all the variables (local and global), and determine if there are any conflicts. However, IMHO, an ounce of prevention is worth a pound of cure in this case; good naming conventions in Python (a great resource - PEP8) are the best ways to prevent errors like this in the first place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With