3

How do I define the function in the importer so that it is visible inside imported? I tried this

importer.py is

def build():
    print "building"

build()

import imported

Whereby, imported.py is simply

build()

Yet, this fails

building
Traceback (most recent call last):
  File "C:\Users\valentin\Desktop\projects\maxim\miniGP\b01\evaluator\importer.py", line 6, in <module>
    import imported
  File "C:\Users\valentin\Desktop\projects\maxim\miniGP\b01\evaluator\imported.py", line 1, in <module>
    build()
NameError: name 'build' is not defined

Update After I have got the response to make the circular import, so that import and imported depend on each other, I feel that I need to make clear that this is not always good. My purpose is to specify some common strategy in the imported module. It will use some user-defined functions, e.g. build. User defines the necessary function(s) and calls the strategy. The point is that the shared strategy must not depend on specific user definitions. I believe that in place of import, I need something like evaluate(imported.py), which I believe is a basic function in any script language, including Python. irc://freenode/python insists that I must use import but I do not understand how.

Val
  • 1
  • 8
  • 40
  • 64
  • Part of our confusion is because that's _exactly what `import` does_, as a side-effect of importing the module itself. (So, if `foo.py` contains `bar = 1 + 1` and you `import foo`, you then have access to `foo.bar == 2` because `foo.py` was evaluated!) – Izkata Nov 04 '13 at 14:59
  • I do not understand which confusion you are talking about. – Val Nov 04 '13 at 15:45

3 Answers3

12

importer.py

def build():
   print("building")

build() #this extra call will print "building" once more.

imported.py

from importer import build
build()

Note that both importer.py and imported.py must be in same directory. I hope this solve your problem

SujitS
  • 11,063
  • 3
  • 19
  • 41
  • Won't it create a curcular reference? How many times is print("building") executed? – Val Oct 31 '13 at 17:02
  • as much as you call build() function. For my case It will print just once. – SujitS Oct 31 '13 at 17:03
  • In fact, I call it twice and in fact, it is executed 3 times. I wonder why not million: you call importer.py, which prints and imports imported.py, which imports the importer.py, which prints(building) and imports the impoted, which imports the importer, which prints(building) and imports the imported, which … – Val Oct 31 '13 at 17:06
  • 4
    Have you tried it yet! using import means to make reference to your module, not to execute it. And a function call build() inside the imported will actually call the function from importer.py which is then executed not more than once. So try it before you ask it – SujitS Oct 31 '13 at 17:11
  • 1
    I have tried it, and in my laptop its just once, and with 2 build() function its twice.. double check your problem I am sure its not the way of python – SujitS Oct 31 '13 at 17:16
  • All I did is prefix the `imported.py` with the `from importer import build` line that you have recommended – Val Oct 31 '13 at 17:17
  • Then it should be working then, check to your importer.py, may be you have two build() function; one for definition and another one is function call. Its not a problem of import anymore. – SujitS Oct 31 '13 at 17:20
  • Ok, I have not noticed that you asked me to rewrite the `importer.py` also. The problem was missing `from importer import build` in the `imported.py`. Your answer does not resolve it though. I cannot import the importer because imported is a common piece that must work in any context (arbitrary importer, whichever `build` function it has defined). Imported must not be tied to specific importer. – Val Oct 31 '13 at 17:47
  • 1
    I have discovered that I need [execfile](http://stackoverflow.com/a/1027739/1083704). Unfortunately enemy does not let me to make this as answer. But let's keep the right answer here. – Val Oct 31 '13 at 18:42
  • @Val If you have multiple implementations of code defining `build`, and only one must be called depending on a certain context, you're not even asking the right question. You've gone down a rabbit hole in the wrong direction. Please, in the future, actually ask about the problem you're facing, _not_ what you assume the answer will be. – Izkata Nov 04 '13 at 01:50
  • @Izkata I asked that at irc://freenode/#python and they told me that I need to single out a common part into another file and use imports. They refused to explain how should I import actually. I, thus, had to resort here. What did I wrong? – Val Nov 04 '13 at 08:30
  • @Val We still don't know what you're trying to do, so this answer was really the best we can do, and it's not what you want. Please [read this and ask a question about what you're actually trying to do](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem/66378#66378), if you still need help. – Izkata Nov 04 '13 at 12:59
  • @Izkata, I have updated the question explaining the limitation of "the best you can do" and why execfile is more appropriate for my task. I wonder why python experts are so blind to notice that and demand more details without explaining what is not clear in what is provided. I have tired explaining why I need this. I won't do any more. Listen Faynman explaining that there is ultimate reason why you need something http://www.youtube.com/watch?v=36GT2zI8lVA I feel that is enough to say that ice is slippery. You ask `why` without even clarifying what are you referring to. – Val Nov 04 '13 at 14:05
7

Imports are not includes: they are idempotent and should always be at the top of a module.

There is no circularity; once import foo is seen, further instances of import foo will not load the module again.

You are getting the NameError because in the context of imported.py, there is no name build, it is known as importer.build().

I have no idea what you are trying to do with code as oddly structured as that.

msw
  • 42,753
  • 9
  • 87
  • 112
  • Importer defines some functions and calls some common code. This way you parametrize your common code. There is nothing strange in this normality. – Val Oct 31 '13 at 17:21
-14

I know that this is a blasphemy but the thing that allows to import a module without tying the imported with importer is easily available in Python as a script language. You can always evaluate a file with execfile

Community
  • 1
  • 1
Val
  • 1
  • 8
  • 40
  • 64
  • 8
    `execfile()` isn't "blasphemy", it's a plain bad idea. Also, it's quite unlike importing. It's clear from your question that this is what you want, but it's not clear _why_ you want this. This is not a normal thing to do in Python, by any means. Structure your project to fit Python, instead. – Thomas Wouters Oct 31 '13 at 18:10