How do I access a main frunction from an import module?

J

Jim

Hi,

I have created an import module. And would like to access a function
from the main script, e.g.,

file abc.py:
###################
def a():
m()
return None
####################

file main.py:
#####################
from abc import *
def m():
print 'something'
return None

a()
######################

python25.exe main.py

Thanks,
Jim
 
R

robert

Jim said:
Hi,

I have created an import module. And would like to access a function
from the main script, e.g.,

file abc.py:
###################
def a():
m()
return None
####################

file main.py:
#####################
from abc import *
def m():
print 'something'
return None

a()
######################

python25.exe main.py

import __main__
....
__main__.m()


but better make a start.py and "import main" - then its symmetric


Robert
 
C

Carl Banks

Jim said:
I have created an import module. And would like to access a function
from the main script, e.g.,

file abc.py:
###################
def a():
m()
return None
####################

file main.py:
#####################
from abc import *
def m():
print 'something'
return None

a()
######################


You can do it with "from __main__ import m" atop abc.py (the module
invoked at the command line is always called __main__).

However, I *highly* suggest you put m in another file. Importing
variables from __main__ would make your program incompatible with many
useful tools. For example, if you invoke the Python profiler on your
code, like this:

python -m profile main.py

it will break your code, because __main__ no longer refers to main.py
but to profile.py (from the Python library). Importing from __main__
adversely affects tools such as PyChecker and PyLint.

The exception to this would be if abc.py is specifically designed as a
utility for interactive use; then it would be ok and useful.


Carl Banks
 
A

Anton Vredegoor

Jim said:
I have created an import module. And would like to access a function
from the main script, e.g.,

file abc.py:
###################
def a():
m()
return None
####################

file main.py:
#####################
from abc import *
def m():
print 'something'
return None

a()

import sys
def a():
sys.modules['__main__'].m()
return None

Anton

'now why would anyone want to do *that* ?'
 
B

Bjoern Schliessmann

Jim said:
I have created an import module. And would like to access a
function from the main script, e.g.,

May I ask why? This style violates "normal" module philosophy.

Regards,


Björn
 
J

Jim

Bjoern said:
May I ask why? This style violates "normal" module philosophy.

Regards,


Björn

Application abc is designed as a complete module. The user is to
script their own functions to work with application abc.

Thanks,
JIm
 
J

John Machin

Jim said:
Hi,

I have created an import module. And would like to access a function
from the main script, e.g.,

file abc.py:
###################
def a():
m()
return None
####################

file main.py:
#####################
from abc import *
def m():
print 'something'
return None

a()
######################

python25.exe main.py

Although there are literally correct answers to your question, the best
answer is "Don't do that. You would be creating circular references
between modules, and run the risk of emulating the mythical ooloo bird
by disappearing up your own fundamental orifice". Some possible
practical solutions:

1. Put the m function in a 3rd file/module. Then any other module which
needs it can import/call.

2. If you think that's not a good idea, then put it in abc.py (it's not
used in main.py in your example).

3. Maybe this will suit what you are really trying to do:

file abc.py:
###################
def a(argfunc): # <<<<<=====
argfunc() # <<<<<=====
####################

file main.py:
#####################
from abc import *
def m():
print 'something'

a(m) # <<<<<=====
######################

4. If you think *that's* not a good idea, then you might like to
explain at a higher level what you are *really* trying to achieve :)
E.g. "Function m is one of n functions in main.py of which abc.py
may/must call 0, 1, or many because blah blah blah ..."

BTW, "return None" at the very end of a function is redundant. The
Python compiler generates "return None" automagically (implicitly!?)
instead of letting you fall off the end of the world. Which book or
tutorial are you using?

BTW #2: "python25.exe main.py" ?? If you are on Windows, have Python
2.4 as your default setup, and are trialling 2.5: you may like to ask
(in a new thread) about more convenient ways of doing it. Otherwise you
might like to tell what you are up to (in a new thread) so that your
problem can be diagnosed correctly and cured :)

HTH,
John
 
F

Fredrik Lundh

Jim said:
Application abc is designed as a complete module. The user is to
script their own functions to work with application abc.

so use execfile() with a prepared namespace:

namespace = { ...stuff to export to the module ... }
execfile("directory/module.py", namespace)

</F>
 
J

Jim

John said:
Although there are literally correct answers to your question, the best
answer is "Don't do that. You would be creating circular references
between modules, and run the risk of emulating the mythical ooloo bird
by disappearing up your own fundamental orifice". Some possible
practical solutions:

1. Put the m function in a 3rd file/module. Then any other module which
needs it can import/call.

2. If you think that's not a good idea, then put it in abc.py (it's not
used in main.py in your example).

3. Maybe this will suit what you are really trying to do:

file abc.py:
###################
def a(argfunc): # <<<<<=====
argfunc() # <<<<<=====
####################

file main.py:
#####################
from abc import *
def m():
print 'something'

a(m) # <<<<<=====
######################

4. If you think *that's* not a good idea, then you might like to
explain at a higher level what you are *really* trying to achieve :)
E.g. "Function m is one of n functions in main.py of which abc.py
may/must call 0, 1, or many because blah blah blah ..."

BTW, "return None" at the very end of a function is redundant. The
Python compiler generates "return None" automagically (implicitly!?)
instead of letting you fall off the end of the world. Which book or
tutorial are you using?

BTW #2: "python25.exe main.py" ?? If you are on Windows, have Python
2.4 as your default setup, and are trialling 2.5: you may like to ask
(in a new thread) about more convenient ways of doing it. Otherwise you
might like to tell what you are up to (in a new thread) so that your
problem can be diagnosed correctly and cured :)

HTH,
John

BTW#1: I have most of the python books from O'Reilly. I'm sure that
some of them say that its a good idea to use 'return None'. However,
most their examples do not us it. Anyway I find that its useful when
reading my own scripts.

BTW#2: I do not have Python 2.4 installed anymore. Therefore, it is
not a trialling problem.

I thought that it would be NICE to keep the application and the user's
script separate from each other, being that python is so flexible.
However, there seems to be no end to the problems that occur by doing
this. So I will abandon this exercise, since it appears not to be a
very good programming practise.

Thanks,
Jim
 
S

Steve

This is an interesting question. It almost looks like a case of
event-driven programming, where main is the plug-in and abc is the
framework.
http://eventdrivenpgm.sourceforge.net/

So how about something like this:

################## abc.py ####################

#------------------------------------------------------------
# an "abstract" function.
# It should be over-ridden in the calling program
#------------------------------------------------------------
def m():
raise AssertionError("You should have over-ridden abstract function
m()")

def a():
m()
return None


########### main.py ####################
import abc # "instantiate" the framework

# define our our "concrete" function m
def m():
print 'something'
return None

#-----------------------------------------------
# override the "abstract" function abc.m()
# with our own "concrete" function m().
# Comment out this line and see what happens.
#-----------------------------------------------
abc.m = m

# invoke the a() function in the abc framework
abc.a()

#################################################
 
J

John Machin

Jim said:
BTW#1: I have most of the python books from O'Reilly. I'm sure that
some of them say that its a good idea to use 'return None'.

Instead of "return None", consider using "return for refund" ;-)
However,
most their examples do not us it. Anyway I find that its useful when
reading my own scripts.

BTW#2: I do not have Python 2.4 installed anymore. Therefore, it is
not a trialling problem.

Looks like it *was* a trialling problem, with weird residual effects.
The point was that it's a very strange practice to (a) name the
executable "python25.exe" [standard installation would produce
C:\Python25\python.exe] (b) want/need to use ".exe" when invoking it.
I thought that it would be NICE to keep the application and the user's
script separate from each other, being that python is so flexible.

Most other people think that that's a very nice idea too; there was
just no clue in your original posting about what you were really trying
to do.
However, there seems to be no end to the problems that occur by doing
this. So I will abandon this exercise, since it appears not to be a
very good programming practise.

So what about my suggestion 3? I got the impression from your reply to
Bjoern that it was a good fit for your case. The functions are in what
we now know to be the user's script, and the app calls them. What
problems?

Cheers,
John
 
J

Jim

Steve said:
This is an interesting question. It almost looks like a case of
event-driven programming, where main is the plug-in and abc is the
framework.
http://eventdrivenpgm.sourceforge.net/

So how about something like this:

################## abc.py ####################

#------------------------------------------------------------
# an "abstract" function.
# It should be over-ridden in the calling program
#------------------------------------------------------------
def m():
raise AssertionError("You should have over-ridden abstract function
m()")

def a():
m()
return None


########### main.py ####################
import abc # "instantiate" the framework

# define our our "concrete" function m
def m():
print 'something'
return None

#-----------------------------------------------
# override the "abstract" function abc.m()
# with our own "concrete" function m().
# Comment out this line and see what happens.
#-----------------------------------------------
abc.m = m

# invoke the a() function in the abc framework
abc.a()

#################################################

Thank you Steve.

You are correct, the project that I'm working on is an event drive
program. And your solution works perfectly for this simple example.
My poroject does actually have what you called an "abstract" function.
Now I will know try to implement it into my project.

Thanks again.
Jim
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top