creating variable in root namespace from module

M

MakaMaka

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!
 
S

Steve Holden

MakaMaka said:
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
 
D

Duncan Booth

MakaMaka said:
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.
 
M

MakaMaka

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
 
S

Steve Holden

MakaMaka said:
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
 
M

MakaMaka

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
 
M

MakaMaka

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
 
D

Duncan Booth

MakaMaka said:
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:
sys._getframe(1).f_locals['a'] = 1

a = 0
print a
f()
print a


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.
 
M

MakaMaka

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
 

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

Forum statistics

Threads
474,289
Messages
2,571,448
Members
48,126
Latest member
ToneyChun2

Latest Threads

Top