469,271 Members | 892 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,271 developers. It's quick & easy.

creating variable in root namespace from module

Hi,
I have a scope related question that I haven't been able to find an
answer to anywhere. Is there a way to have a function in an imported
module add variables to the scope of the calling script? Basically,
can I have the following:

#root.py
import some_module.py

some_module.afunction() # <== create a variable x1=1 and add it to the
scope of root.py

print x1 # <== would print 1

I know this can be accomplished by passing the what globals() returns
into the function; however, I'm wondering if there is a way to do this
without passing anything to the function.

Thanks!

Mar 10 '06 #1
8 3472
MakaMaka wrote:
Hi,
I have a scope related question that I haven't been able to find an
answer to anywhere. Is there a way to have a function in an imported
module add variables to the scope of the calling script? Basically,
can I have the following:

#root.py
import some_module.py

some_module.afunction() # <== create a variable x1=1 and add it to the
scope of root.py

print x1 # <== would print 1

I know this can be accomplished by passing the what globals() returns
into the function; however, I'm wondering if there is a way to do this
without passing anything to the function.

There are clever technical ways to do this, but what's the use case?
There's almost certainly a better way to accomplish what you want.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd www.holdenweb.com
Love me, love my blog holdenweb.blogspot.com

Mar 10 '06 #2
MakaMaka wrote:
I have a scope related question that I haven't been able to find an
answer to anywhere. Is there a way to have a function in an imported
module add variables to the scope of the calling script? Basically,
can I have the following:

#root.py
import some_module.py

some_module.afunction() # <== create a variable x1=1 and add it to the
scope of root.py

print x1 # <== would print 1

I know this can be accomplished by passing the what globals() returns
into the function; however, I'm wondering if there is a way to do this
without passing anything to the function.


Try:

x1 = some_module.afunction()

This has the advantage that in some other script you can decide to give the
variable a meaningful name, and it doesn't have to be the same as the name
you used in your first script.

You can easily extend this technique to set several variables in the
calling script:

x1, y2, z3 = some_module.afunction()

You don't even have to restrict yourself to global variables, this
technique will even work to let the function set variables in another
function's local namespace or attributes on some arbitrary object.
Mar 10 '06 #3
Hi again,
Steve-
I'm trying to use python to model reliability. Basically, I want to
read an XML file in that defines a bunch of variables, that are then
accessible from the python interpreter. For example:
import reliability

reliability.read_xml("c:\\somefile.xml") #<== defines x1, x2, x3

result = x1+x2+x3

This tool will be used by people who are not necessarily coders and I
don't want them to have to deal with passing global namespaces etc.

Duncan-
I like your idea; however, I don't want the user to actually have to
know the structure of the xml file, so I don't think I can do it this
way. There might be 3, 4 or 1000 variables that the function needs to
create.

Any other ideas? What clever technical ways have been used? I know I
can just have the function add the variables to the global namespace of
the module and then access them like

reliability.x1

or in a dict or something, but I think this might confuse some of my
potential users who aren't familiar with Object Oriented programming
(think electrical engineers who still code in Fortran).

Thanks,
Justin

Mar 10 '06 #4
MakaMaka wrote:
Hi again,
Steve-
I'm trying to use python to model reliability. Basically, I want to
read an XML file in that defines a bunch of variables, that are then
accessible from the python interpreter. For example:
import reliability

reliability.read_xml("c:\\somefile.xml") #<== defines x1, x2, x3

result = x1+x2+x3

This tool will be used by people who are not necessarily coders and I
don't want them to have to deal with passing global namespaces etc.

Duncan-
I like your idea; however, I don't want the user to actually have to
know the structure of the xml file, so I don't think I can do it this
way. There might be 3, 4 or 1000 variables that the function needs to
create.

Any other ideas? What clever technical ways have been used? I know I
can just have the function add the variables to the global namespace of
the module and then access them like

reliability.x1

or in a dict or something, but I think this might confuse some of my
potential users who aren't familiar with Object Oriented programming
(think electrical engineers who still code in Fortran).

Thanks,
Justin

Well, one way that springs to mind is to put the definitions in a
dictionary and then to do

globals.update(d)

to add them all to the global namespace. You'll have to be careful about
not shadowing built-in names, though, since the interpreter searched the
global namespace before the built-ins. You'd have to pass the gloabl
dict into the function, though, because it lives in another module.

There are various ways you can use data from the sys module to gain
access to the caller's local namespace. I'm not sure you want to go that
far, though.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd www.holdenweb.com
Love me, love my blog holdenweb.blogspot.com

Mar 10 '06 #5
Steve,
I think I actually need to get the caller's local namespace. How do I
do that using sys? I read the documentation and can't find anything
specific. For example, if I have module A and it imports module B, I
want module B to add variables to A's global namespace. Python has to
store this info somewhere in order to return to A after a function is
run in B. I can certainly look at it the Komodo debugger call stack.
Thanks,
-Justin

Mar 10 '06 #6
Ok, I figured it out. Thanks for your help guys. If anybody else is
searching this group looking for the answer, you want the
sys._getframe() function.

sys._getframe(1).f_locals['a'] = 1

if you put the above in a function in a module, it creates a variable
'a' in the namespace of whatever calls the function in the module. I
know this may make people cringe, but since I'm trying to basically
create a language, of which python is a subset, it's actually exactly
what I need to do.

-Justin

Mar 10 '06 #7
MakaMaka wrote:
Ok, I figured it out. Thanks for your help guys. If anybody else is
searching this group looking for the answer, you want the
sys._getframe() function.

sys._getframe(1).f_locals['a'] = 1

if you put the above in a function in a module, it creates a variable
'a' in the namespace of whatever calls the function in the module. I
know this may make people cringe, but since I'm trying to basically
create a language, of which python is a subset, it's actually exactly
what I need to do.


Err, no. Actually it doesn't:
import sys
def f(): sys._getframe(1).f_locals['a'] = 1

def g(): a = 0
print a
f()
print a

g() 0
0 a = 42
f()
a 1


Code like that may sometime update the caller's namespace, but for local
variables it will usually have no effect. Also, any effect it does have may
vary wildly across different Python implementations or versions.

In short, don't do that.
Mar 10 '06 #8
Ok, but it seems to be working exactly as I need it to right now under
win32. I'll try it on linux. Can you suggest an alternative method?
Or suggest when this won't work?

Thanks,
-Justin

Mar 11 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

23 posts views Thread by Fuzzyman | last post: by
3 posts views Thread by dotNETnews | last post: by
4 posts views Thread by tshad | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.