2

how do i import a function and a dictionary that mutually imports each other. These two files are already in the same directory thus, there is no nid to import sys. Also, i this it is recursive that is why it is unable to import. How do i import a dictionary from each other's file without making it recursive and causing an error?

I did go to this website here but it did not answer my question nor did it provide any example code to guide me thus, i created this question with a test code to explain my issue.

let's say i have these two files: boxA and boxR, each has a dictionary keyA and keyR and functions named generatekeyA and generatekeyR

in boxA:

import json 
from tinydb import TinyDB, Query
from boxR import keyR

def generatekeyA():

    keyA = {}

    serialnoA = 'Serial_noA'
    secretidA = 'Secret_idA'

    count = 0
    while (count <5): 

    serial = generate key 
    id = generate id 


    keyA[serialnoA].append(serial)
    keyA[secretidA].append(id)


    with open("/home/pi/Desktop/json/output.json", 'w+'):
        db = TinyDB('/home/pi/Desktop/json/output1.json')
        table = db.table('A KEYS')
        db.insert_multiple([{'Serial number A' :  keyA[serialnoA]}])
        db.insert_multiple([{'Secret id A' : keyA[secretidA]}])
        db.insert_multiple([{'Secret id R' : keyR[secretidR]}])

generatekeyA()

in boxR:

import json 
from tinydb import TinyDB, Query
from boxA import keyA

def generatekeyR():

    keyR = {}

    serialnoR = 'Serial_noR'
    secretidR = 'Secret_idR'

    count = 0
    while (count <5): 

    serialR = generate key 
    idR = generate id 


    keyR[serialnoR].append(serialR)
    keyR[secretidR].append(idR)


    with open("/home/pi/Desktop/json/output2.json", 'w+'):
        db = TinyDB('/home/pi/Desktop/json/output2.json')
        table = db.table('R KEYS')
        db.insert_multiple([{'Serial number R' :  keyR[serialnoR]}])
        db.insert_multiple([{'Secret id R' : keyR[secretidR]}])
        db.insert_multiple([{'Secret id A' : keyA[secretidA]}])


generatekeyA()

Let me explain the codes above. I have 2 files that generate keys for me after which, i have to export the output into a json file. output.json file prints out keyA's own serial no and secret id and only keyR's secretid and viceversa into output2.json file. but the thing is that eventhough i research on recursive outputs, i still do not understand how to fix it because it does not provide any sample code as a guide. What is the best way to approach this such that i do not have to make much changes to the file(s)?

Error tells me that it could be a recursive error:

Traceback (most recent call last):
File "/home/pi/Desktop/boxA.py", line 7, in <module>
from boxR import keyR
File "/home/pi/Desktop/boxR.py", line 11, in <module>
from boxA import keyA
File "/home/pi/Desktop/boxA.py", line 7, in <module>
from boxR import keyR
ImportError: cannot import name 'keyA'
DanielWinser
  • 151
  • 1
  • 3
  • 8
  • I'm not sure that this would be possible, because of the recursion that's happening. Python assumes you need ```keyR``` to run ```boxA``` and you need ```keyA``` to run ```boxR```, and neither can satisfy the other. It looks like (from this snippet) that you don't specifically *need* those variables though? – Jack Parkinson Jun 14 '17 at 07:47
  • 1
    Possible duplicate of [Python circular importing?](https://stackoverflow.com/questions/22187279/python-circular-importing) – Jérôme Jun 14 '17 at 07:48
  • @Jérôme no, the link above did not provide an example code and example answer for me to understand. – DanielWinser Jun 14 '17 at 08:14
  • @ISOmetric however, i need to run the codes in keyA and at the same time print out an output from key R and vice versa. What is the best way to approach this? – DanielWinser Jun 14 '17 at 08:21
  • Well you do have to generate one before the other, otherwise it just won't work. I think you'll have to figure out a way to give one of them priority. But it might be a little easier to understand exactly what was required if you showed more code? – Jack Parkinson Jun 14 '17 at 08:26
  • @ISOmetric hi! thank you for your help!! i've updated my question, i hope it is sufficient for you to understand my dilemma. – DanielWinser Jun 14 '17 at 08:56
  • 1
    I'm a little unsure about your indentation - is all of the content part of the ```generatekeyA/R()``` function or have you defined an empty function? Because I don't think that it would work anyway, laid out like that. – Jack Parkinson Jun 14 '17 at 09:28
  • @ISOmetric Oops my bad!!! ive edited the indentation already. The function is not empty. Im trying to mutuall import the files and dictionary from each other's file but its recursive – DanielWinser Jun 15 '17 at 01:37
  • Where does that ```while``` loop end? does it contain the ```with``` statement at the end? – Jack Parkinson Jun 15 '17 at 07:41
  • Also you never update ```count```, from what I can see, so the ```while``` loop will go on forever. – Jack Parkinson Jun 15 '17 at 07:52

3 Answers3

1

This is a circular dependency. I am not sure how you can solve it without changing the basic structure of the modules and therefore the dependency graph. Why don't you try to define both the dicts in a separate file and import them. As it looks like form your code they are empty dicts anyway.

You may find this article interesting. In essence, when you do a recursive dependency the imported modules find each other as empty module at the time of import statement execution. And thus this error shows up

SRC
  • 2,123
  • 3
  • 31
  • 44
  • Seems the website is down. [here](https://www.dangtrinh.com/2013/09/python-circular-imports.html) is another example that may be useful – SRC Dec 05 '21 at 05:23
0

in boxA:

def generatekeyA():
  from boxR import keyR
  do whatever you need to with keyR

keyA = {}

in boxR:

def generatekeyR():
  from boxA import keyA
  do whatever you need to with keyA

keyR = {}

UPDATE

If you're still seeing the issue, you probably haven't removed the import for keyR from the global scope of boxA and the import of keyA from the global scope of boxR. For example, this works as expected:

################# The file, boxR.py
def generatekeyR():
  from boxA import keyA
  print 'In generatekeyR'

keyR = {}

################# The file, boxA.py
def generatekeyA():
  from boxR import keyR
  print 'In generatekeyA'

keyA = {}

################# The file, box.py
#!/usr/bin/env python
import boxR
import boxA
from boxR import generatekeyR
from boxA import generatekeyA

generatekeyR()
generatekeyA()

From the bash prompt:

> ./box.py
In generatekeyR
In generatekeyA
Sniggerfardimungus
  • 11,583
  • 10
  • 52
  • 97
  • hi! ive tried to do what you suggested above but it did not work. both files could not import each others dictionaries – DanielWinser Jun 14 '17 at 09:02
0

I'm still struggling to figure out the exact shape of your code, which is crucial in Python. In future it would be helpful to read over your question more thoroughly and be certain the formatting is correct.

Based on some assumptions I've made (most importantly that the with statement that adds to the database occurs outside the while loop) here is what I've come up with. In summary, the changes are:

  1. Changed the key generation functions to return the keys that they generate.

  2. Created a new Python file (called new.py, but you can call it whatever you want) which handles the updating of the database.

  3. Imported the generation functions into new.py and called them there, before executing the with statement that requires both keys.

And here is the code that I ended up with. Hope it helps.

boxA.py

def generatekeyA():

    keyA = {}

    serialnoA = 'Serial_noA'
    secretidA = 'Secret_idA'

    count = 0
    while (count <5): 

        serial = generate key 
        id = generate id 

        keyA[serialnoA].append(serial)
        keyA[secretidA].append(id)

        # Also need to update count

    return keyA

boxR.py

def generatekeyR():

    keyR = {}

    serialnoR = 'Serial_noR'
    secretidR = 'Secret_idR'

    count = 0
    while (count <5): 

        serialR = generate key 
        idR = generate id

        keyR[serialnoR].append(serialR)
        keyR[secretidR].append(idR)

        # Also need to update count

    return keyR

new.py

import json 
from tinydb import TinyDB, Query
from boxA import generatekeyA()
from boxR import generatekeyR()

keyA = generatekeyA()
keyR = generatekeyR()

with open("/home/pi/Desktop/json/output2.json", 'w+'):
    db = TinyDB('/home/pi/Desktop/json/output2.json')
    table = db.table('R KEYS')
    db.insert_multiple([{'Serial number R' :  keyR[serialnoR]}])
    db.insert_multiple([{'Secret id R' : keyR[secretidR]}])
    db.insert_multiple([{'Secret id A' : keyA[secretidA]}])
Jack Parkinson
  • 681
  • 11
  • 35