Pass variable between python scripts

Question:

I’m sure this is very simple but I’ve been unable to get it working correctly. I need to have my main python script call another python script and pass variables from the original script to the script that I’ve called

So for a simplistic example my first script is,

first.py
x = 5
import second

and my second script is,

second.py 
print x

and I would expect it to print x but I get

NameError: name 'x' is not defined

I’m not sure if import is right way to achieve this, but if someone could shed light on it in a simple way that would be great!

thanks,


EDIT

After reading the comments I thought I would expand on my question. Aswin Murugesh answer fixes the import problem I was having, however the solution does not have the desired outcome as I can not seem to pass items in a list this way.

In first.py I have a list which I process as follows

for insert, (list) in enumerate(list, start =1):
    'call second.py passing current list item'

I wanted to pass each item in the list to a second python file for further processing (web scraping), I didn’t want to do this in first.py as this is meant to be the main ‘scan’ program which then calls other programs. I hope this now make more sense.

Thanks for the comments thus far.

Asked By: DavidJB

||

Answers:

use the following script:

first.py:

x=5

second.py

import first
print first.x

this will print the x value. Always imported script data should be referenced with the script name, like in first.x

Answered By: Aswin Murugesh

When you call a script, the calling script can access the namespace of the called script. (In your case, first can access the namespace of second.) However, what you are asking for is the other way around. Your variable is defined in the calling script, and you want the called script to access the caller’s namespace.

An answer is already stated in this SO post, in the question itself:

Access namespace of calling module

But I will just explain it here in your context.

To get what you want in your case, start off the called script with the following line:

from __main__ import *

This allows it to access the namespace (all variables and functions) of the caller script.

So now your calling script is, as before:

x=5
import second

and the called script is:

from __main__ import *
print x

This should work fine.

Answered By: Abhranil Das

Try use exec
Python3.5:

first.py

x=5
exec(open('second.py').read())

second.py

print(x)

You can also pass x by using:

x=5
myVars = {'x':x}
exec(open('second.py').read(), myVars)

Not sure if this is a good way.

Answered By: Z-Jiang

To avoid namespace pollution, import the variables you want individually: from __main__ import x, and so on. Otherwise you’ll end up with naming conflicts you weren’t aware of.

Answered By: Grant Palmer

Finally,

I created a package for Python to solve this problem.


Install Guli from PIP.

$ pip install guli

Guli doesn’t require installing any additional PIP package.

With the package you can

Guli can be used to pass between different Python scripts, between many processes or at the same script.
pass variables between main Process and another (Multiprocess) Process.

  • Pass variables between different Python scripts.
  • Pass variables between ‘Main Process’ and another (Multiprocess) Process.
  • Use variables at the same script.
  • Create / Delete / Edit – GuliVariables.

Example

import guli
import multiprocessing

string = guli.GuliVariable("hello").get()
print(string) # returns empty string ""

def my_function():
  ''' change the value from another process '''
  guli.GuliVariable("hello").setValue(4)

multiprocessing.Process(target=my_function).start()

import time
time.sleep(0.01) # delay after process to catch the update


string = guli.GuliVariable("hello").get()
print(string) # returns "success!!!"

Hope I solved the problem for many people!

Answered By: red alert
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.