The main question
You can overwrite the variable from b.py with the following code:
import a
a.h = 'actually replaced value'
Note: actually adding that to a.py will still give the following result:
>$ python b.py -h
this is h from a.py
this is h from b.py
Creating the wanted behavior
First note that you can verify that the value of h gets changed with the following code:
a.py:
import sys
h = 'this is h from a.py'
for i in sys.argv:
if i in ['-h']:
print(h)
def what_is_h():
print('h:', h)
b.py:
import sys
from a import h, what_is_h
import a
what_is_h()
a.h = h = 'this is h from b.py'
what_is_h()
for i in sys.argv:
if i in ['-h']:
print(h)
This results in the following:
this is h from a.py
h: this is h from a.py
h: this is h from b.py
this is h from b.py
The first what_is_h call shows the original h value and the second shows the modified value. The problem is a.py and b.py seem to have different versions of the variable h this is what is called scope. When you use the import statement python parses your file and runs the code. The way you can prevent this automatic running of the code is by placing it in a function, importing it and running it from b.py preferably passing h as an argument (since global state is usually bad practice in python).
"What if I want to run a function from a.py too but only if I run it directly?"
Now if you want a function executed when you run a.py or b.py but run the function in a.py only if it is run directly you can add the following to the bottom of your script file:
if __name__ == '__main__':
my_function()
This will run the function my_function only when you execute $> python a.py.
Note that when importing a.py it will not run my_function unless run otherwise.
How does this work?
__name__ is a built-in global variable that stores the "name" the python interpreter gives to python scripts. The file that is run is given the __name__ '__main__'. Now when importing something from a.py __name__ will equal 'a' and my_function will not run.
Further style notes and tips for your code
instead of
if i in ['-h']:
# ... your code
do
if i == '-h':
# ... your code
if you want to check for multiple flags later you can change it.
- checking if something is in a list or sequence-like object:
if you only want to check if -h is in sys.args you can do:
if '-h' in sys.args:
# ... your code
instead of
for i in sys.args:
if i == '-h':
# ... your code
- parsing, handling and dealing with command line arguments
If you plan to do more complex things with arguments there is library that should be included by default with every installation of python, namely the argparse library.
I hope I was able to help.
from a import hbelowh=..... The way you have it written, you are overwritinghfroma.pya.pyall executes before the equivalent loop inb.py.a.h; you are simply initializingb.hwith the value ofa.h, then immediately assigning a new value tob.h.