Python modules: functions calling each other
Asked Answered
E

2

7

I have got myself very confused. I have a set of python functions, all of which I've bunged together in a file called (let's say) useful.py. I can then read the module into my ipython with

 import useful as uf

and then I can access individual functions with

 uf.meaning_of_life()

and so on. Standard stuff.

However - some functions in this file call on other functions. I can call a single function any time with uf., but what about functions which call each other? If a function called eat makes reference to another function called chew, how does eat know where to find chew? I can call both as uf.eat and uf.chew.

I can ignore all of this by simply doing execfile('useful.py') which works perfectly well, but I would like to get more of a handle on the module system.

Currently when I use import my attempt to use my functions produces errors; when I use execfile everything works fine.

I appreciate that this might be construed as very much a beginners question, but I am coming to Python from a Matlab background, and my natural inclination is to use execfile. Pointers to information would be very welcome.

Externalization answered 10/1, 2015 at 11:51 Comment(4)
eat and chew being functions in the same module can refer to each other by their unqualified names eat and chew.Commiserate
If you really must import everything in 'useful.py' into the namespace of your current python module, from useful import * will import everything except names prefixed with '_'. Then they can be accessed from the current module as chew rather than uf.chew. This practice is generally frowned on, because you suddenly end up not knowing what names are already defined.Zins
Incidentally, what error is coming up? And what's wrong with using uf.chew?Zins
I'll see if I can provide a clearer explanation of my issues, but as it's currently 1.30am I think I might get some sleep first! Thank you for all your help and advice so far.Externalization
P
7

What you need to understand first in order to get what's happening is that every module is its own local namespace.

If you have a module like this:

def chew():
    print('chewing')

def eat():
    print('eating')
    chew()

Isn't it obvious that eat can call chew without any problems? They're defined at the same level, in the global (module) scope, so clearly they can see each other.

Now we do the following in another module:

import useful as uf

uf.eat()

In order to access chew, we need to write uf.chew, the same way we have typed uf.eat. We need to do this because we are in another module. In order for us to do any of that we have had to import useful, so that our module knows of it. Our knowledge of the useful module is that its contents are added to the uf name.

That is our point of view. But the useful module knows everything about itself. Nothing has changed there, it doesn't need to import itself to access its contents, and it doesn't know anything about other modules that it has not imported itself.

So to answer, eat knows how to find chew because they are in the same module, and therefore in the same scope.

Perished answered 10/1, 2015 at 12:58 Comment(5)
Many thanks indeed for your clear explanation. So let me get this clear: eat() can happily access chew() because they're in the same module, but from my point of view I can only access each of them as uf.eat() and uf.chew(). That makes sense. However, the fact remains that if I use import then some of the functions simply don't work, but if I read the file with execfile they all work perfectly. I'm not sure what I'm doing wrong...Externalization
It's likely that you have done something wrong unadvertely in your module. If yould post a SSCCE in your question, I might be able to help you with it.Perished
I've put a file up at docs.google.com/document/d/… which contains a brief explanation, and the offending code. Many thanks!Externalization
@Externalization That is not a SSCCE. I've tried to run it a few times and I can't reproduce your problem. Your current question is an obvious case of the (XY problem)[meta.stackexchange.com/questions/66377/what-is-the-xy-problem] and the real question might be better suiten on (Code Review)[codereview.stackexchange.com/].Perished
Ah, well - this is getting into territory way beyond my limited knowledge. But thank you for your time and advice! I'll keep plugging away, and at the worst I can always fall back on 'execfile'.Externalization
U
0

Firstly its advisable to use from somefile import definition as something let me use your function definitions to give you a clear picture. I will write simple functions to eat and chew. where chew will references eat.

useful.py

def eat():
    print 'Eaten'

def chew():
    eat()

main File.py code

from useful import chew as uf

uf()

By calling uf alias for chew function which references the eat function. Welcome to python.

Unwashed answered 10/1, 2015 at 12:42 Comment(1)
Unless you're only using a single (or a few) functions with very obvious names or, or a class of the same name as the module, doing a import useful is ok as it imports a single name under which every function exists instead of polluting the current namespace. This answer is also not really an answer to the original question (unless I got it wrong).Perished

© 2022 - 2024 — McMap. All rights reserved.