-2

I am having trouble making variables accessible among different python scripts. I have three scripts: shared.py test1.py test2.py
In shared.py, I define a dictionary devices and initialize it.

devices = {}

In test1.py, I import shared.py and add some value into devices

import shared
shared.devices['item1': 'item1']

In test2.py, I import shared.py and try to print the updated devices in shared.py

import shared
print shared.devices

Instead of printing the updated value, it gives me an empty dictionary. My understanding is that when I imported shared in test2.py, codes in shared.py are executed again, so it leads to the re-initialization of devices

Is there a way that I can access the updated devices in test2.py? Thanks in advance.

UPDATE1: I changed my shared.py test1.py and test2.py according to a similar solution from link and then added test3.py

# shared.py
def init():
    global devices
    devices = {}

# test1.py
import shared

def add(key, value):
    shared.devices[key] = value

# test2.py
import shared
import test1.py

shared.init()
test1.add('key1', 'value1')
print shared.devices

# test3.py
import shared
print shared.devices

I executed the scripts in the following order:
python test1.py (fine)
python test2.py (fine)
python test3.py (which gives me an error:"AttributeError: 'module' object has no attribute 'devices'")

UPDATE2: To make my question more realistic. I have a login.py which takes a few arguments and tries to connect to a switch.
For example:
python login.py --ip 10.1.1.1 --username admin --password admin

# login.py - pseudocode
switch = Switch() #create an object of Router class
switch.connect(ip, username, password) #take the arguments from the command line and try to connect to a router
switch_dict[admin] = switch #add switch instance to a shared dictionary switch_dict, which will be used by over scripts as well.

After connecting to a switch, I then need to execute another script vlan.py to create a vlan on that switch

# vlan.py - pseudocode
# first I need to get the switch that was created by admin, not other users
my_switch = switch_dict['admin']
# Then I can perform some configuration on vlan
my_switch.createvlan()

The problem is how can I create and store a dictionary switch_dict that can be shared and accessed by other scripts??

Community
  • 1
  • 1
  • I'm not sure if this is just for understanding, but if you are doing this in real code you should probably think about a different architecture. – Slater Victoroff Aug 03 '15 at 04:23
  • possible duplication: http://stackoverflow.com/questions/13034496/using-global-variables-between-files-in-python – mission.liao Aug 03 '15 at 04:27
  • @SlaterTyranus Any suggestions? – yin_bill_wang Aug 03 '15 at 04:29
  • Is your test2.py imported in test1.py ? If not , shared would not keep data across different runs. – Anand S Kumar Aug 03 '15 at 05:07
  • @mission.liao First, thanks for providing a similar case which I can study. But my situation is a bit different. In my case, I may have test3.py test4.py etc., which all need access to the `shared.devices`. In other words, test2.py test3.py test4.py are like `main.py` in the mentioned question. – yin_bill_wang Aug 03 '15 at 05:25
  • @yin_bill_wang If the execution order is modification -> print, then you should be able to see expected result (I just tried), what's the execution order of test1.py and test2.py? – mission.liao Aug 03 '15 at 05:39
  • If `test1.py` and `test2.py` are separate programs there's no easy solution, and definitely not a transparent catch-all solution. You have to be more specific on what the data is, how it's accessed and modified. Whether the data should be kept between runs (well technically it does in some sense since `test1.py` and `test2.py` are separate runs), or in what circumstances is will be reset. – skyking Aug 03 '15 at 05:58
  • @mission.liao The execution orders is test1.py then test2.py. Did you verify using the solution provided from the possible duplication? I changed my test1.py and test2.py according to the suggestion. When I added another script test3.py which simple has the content `import shared` `print shared.devices`. Then I execute test1.py(works fine), then test2.py(works fine), then execute test3.py gives me "AttributeError: 'module' object has no attribute 'devices'" – yin_bill_wang Aug 03 '15 at 05:59
  • each run of 'python' means a fresh restart, that's why your test3.py won't work. You need a real 'main.py' to call all these stuffs. – mission.liao Aug 03 '15 at 06:16
  • @mission.liao Thanks. I guess having a real 'main.py' is the only solution then. – yin_bill_wang Aug 03 '15 at 06:23

1 Answers1

0

You need some form of shared storage. You can use (depending on what you are doing):

  1. A queue or a pipe (documentation).

  2. Shared memory (documentation).

  3. A third, independent store like a file (you can use json or pickle to serialize the object), memcache, redis, sqlite or a database.

The point being that this is not trivial and you need to decide (based on the application) which option works for you.

Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
  • 2. The documentation says: "As mentioned above, when doing concurrent programming it is usually best to avoid using shared state as far as possible. This is particularly true when using multiple processes.". So the question is if he has done the best to avoid that? – skyking Aug 03 '15 at 06:40
  • @skyking I've updated my question to make it more realistic and I hope it will make my question more clearer. Could you please have a look at it again? – yin_bill_wang Aug 03 '15 at 07:57
  • @yin_bill_wang It look's like you're not accessing the data concurrently, and it looks like only one scripts modifies the date, that is good. The solution for your problem could be the number 3. Basically you have to save the data when `login.py` finishes and then read the data in `vlan.py`. If you don't expect concurrency you could use `pickle` for that. – skyking Aug 03 '15 at 08:02