0

I am trying to better understand Pythons modules, coming from C background mostly.

I have main.py with the following:

def g():

    print obj # Need access to the object below

if __name__ == "__main__":

    obj = {}

    import child

    child.f()

And child.py:

def f():

    import main

    main.g()

This particular structure of code may seem strange at first, but rest assured this is stripped from a larger project I am working on, where delegation of responsibility and decoupling forces the kind of inter-module function call sequence you see.

I need to be able to access the actual object I create when first executing main python main.py. Is this possible without explicitly sending obj as parameter around? Because I will have other variables and I don't want to send these too. If desperate, I can create a "state" object for the entire main module that I need access to, and send it around, but even that is to me a last resort. This is global variables at its simplest in C, but in Python this is a different beast I suppose (module global variables only?)

Armen Michaeli
  • 8,625
  • 8
  • 58
  • 95
  • the file is not necessarily called main, the lines after `if __name__ == "__main__":` are only executed if you run the script directly and ignored if you import anything from it. – Padraic Cunningham Jul 17 '14 at 09:53
  • 3
    "delegation of responsibility and decoupling forces the kind of inter-module function call sequence you see." In the place where you learned these fancy terms, did you perhaps also see "dependency injection"? What's wrong with just passing things in parameters? – Karl Knechtel Jul 17 '14 at 10:30
  • Karl, what are you trying to say with your sarcastic remark ending with "dependency injection"? I did not namedrop terms just for its own sake, but I hope you were at least amused :-) I will not go into the wrongs of parameter passing in this case. – Armen Michaeli Jul 17 '14 at 10:43
  • @amn: a circular dependency between two modules is a sure design smell. If what you're after is decoupling, then you're getting it wrong, since you now have two tightly coupled modules (not to mention shared global state etc). Passing your dependencies as parameters is surely a better way to decoupling. – bruno desthuilliers Jul 17 '14 at 12:32
  • bruno, did you take into account the answer I submitted below? As to your comment, I don't see it as circular - each module is imported once, and that's it. Also, they are not dependencies, the variables are of no use to `f()`, they are supposed to be only visible in `g()` which is in the same module as variables themselves. – Armen Michaeli Jul 17 '14 at 13:06

1 Answers1

0

One of the solutions, excluding parameter passing at least, has turned to revolve around the fact that when executing the main Python module main as such - via f.e. python main.py where if clause suceeds and subsequently, obj is bound - the main module and its state exist and are referenced as __main__ (inspected using sys.modules dictionary). So when the child module needs the actual instance of the main module, it is not main it needs to import but __main__, otherwise two distinct copies would exist, with their own distinct states.

'Fixed' child.py:

def f():

    import __main__

    __main__.g()
Armen Michaeli
  • 8,625
  • 8
  • 58
  • 95
  • That is a solution sufficiently awkward to suggest a deeper problem. – jonrsharpe Jul 17 '14 at 15:21
  • Maybe so, but then again, your comment appears insufficiently informative to suggest a meaningful response. Would you care to elaborate on the supposed awkwardness of my solution? – Armen Michaeli Jul 18 '14 at 08:39
  • 1
    As Karl and Bruno have pointed out in the comments, the dependency between the two modules suggests that your "delegation of responsibility and decoupling" has not been successful. However, this is very difficult to answer in the general case; the example in your post is trivial to refactor, but that probably doesn't help your specific case. I don't know how big your modules are, but perhaps consider submitting the two in question for [code review](http://codereview.stackexchange.com). – jonrsharpe Jul 18 '14 at 09:19