473,383 Members | 1,795 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

funcs vs vars in global namespace

Getting no answer yesterday, I've done some investigation and I
obviously don't understand how python namespaces work. Here's a test
program:

#!/usr/bin/python

b = 2

def sumWithGlobal(a):
return a + b

#this is easy
print 'Case 1: Normal function call:'
print sumWithGlobal(2)
print

#If you don't send a globals dict with eval, it uses the one from
#the calling program, so this is basically the same as Case 1
print 'Case 2: Function call from inside an eval using the same globals():'
print eval("sumWithGlobal(2)")
print

#Since I'm sending in a globals dict but haven't included a defintion
#for sumWithGlobal(), obviously this will fail (commented out to get
#past the error)
print 'Case 3: Attempt to replace just the global var b (fails for known
reason)'
#print eval("sumWithGlobal(2)", {'b':3})
print

#Here is define sumWithGlobals but not b and it still works. Why?
#Shouldn't I get an error that b is undefined, since it isn't in the
#globals dict of the eval?
print 'Case 4: Attempt to set just the function sumWithGlobal (succeeds
for unknown reason'
print eval("sumWithGlobal(2)", {'sumWithGlobal':sumWithGlobal})
print

#And finally I define both but I still get output as if b = 2
#Again, why? In the eval's global, b = 3, doesn't it?
print 'Case 5: Attempt to set both function and var. (var has wrong value)'
print eval("sumWithGlobal(2)", {'sumWithGlobal':sumWithGlobal, 'b':3})
print
If I add a "print globals()" to sumWithGlobal, I see {'b':2} in there in
cases 1, 2, 4 and 5. What am I doing wrong?
Jul 18 '05 #1
13 1615
David Rysdam <dr*****@ll.mit.edu> wrote:
...
def sumWithGlobal(a):
return a + b ... #Here is define sumWithGlobals but not b and it still works. Why?
#Shouldn't I get an error that b is undefined, since it isn't in the
#globals dict of the eval?
print 'Case 4: Attempt to set just the function sumWithGlobal (succeeds
for unknown reason'
print eval("sumWithGlobal(2)", {'sumWithGlobal':sumWithGlobal})
print
The function sumWithGlobal, internally, uses the global dictionary of
the module it was defined in, NOT that of the module it's being called
from, including the "kinda sorta pseudo" module you have within an eval.
This also explains:
If I add a "print globals()" to sumWithGlobal, I see {'b':2} in there in
cases 1, 2, 4 and 5. What am I doing wrong?


You're misunderstanding Python globals: they are per-module, not "across
all modules".
Alex
Jul 18 '05 #2
Alex Martelli wrote:
David Rysdam <dr*****@ll.mit.edu> wrote:
...
def sumWithGlobal(a):
return a + b


...
#Here is define sumWithGlobals but not b and it still works. Why?
#Shouldn't I get an error that b is undefined, since it isn't in the
#globals dict of the eval?
print 'Case 4: Attempt to set just the function sumWithGlobal (succeeds
for unknown reason'
print eval("sumWithGlobal(2)", {'sumWithGlobal':sumWithGlobal})
print

The function sumWithGlobal, internally, uses the global dictionary of
the module it was defined in, NOT that of the module it's being called
from, including the "kinda sorta pseudo" module you have within an eval.
This also explains:

If I add a "print globals()" to sumWithGlobal, I see {'b':2} in there in
cases 1, 2, 4 and 5. What am I doing wrong?

You're misunderstanding Python globals: they are per-module, not "across
all modules".
Alex


OK, I can kind of understand that. I'm not sure what the point of being
able to specify the globals for an eval() is then, but if it doesn't do
what I want it doesn't do what I want.

What I want to do is be able to run multiple scripts that use the same
global variable and function names but be able to have my master script
define those variables and functions programmatically. Can I do that
with the rexec sandbox stuff? Or is rexec more about keeping the
exec()'d code from doing things than specifying precisely what it can do?
Jul 18 '05 #3
David Rysdam <dr*****@ll.mit.edu> wrote:
...
You're misunderstanding Python globals: they are per-module, not "across
all modules".
OK, I can kind of understand that. I'm not sure what the point of being
able to specify the globals for an eval() is then, but if it doesn't do
what I want it doesn't do what I want.


The point is clearer when what you're passing to eval is an expression:

eval('a+b', dict(a=23, b=99)).

What I want to do is be able to run multiple scripts that use the same
global variable and function names but be able to have my master script
define those variables and functions programmatically. Can I do that
with the rexec sandbox stuff? Or is rexec more about keeping the
exec()'d code from doing things than specifying precisely what it can do?


rexec has been removed because it did not offer the security it
purported to offer (it was about keeping code from doing bad things, but
it reallly didn't), sigh.

You can do what you want for example by setting the values you want in
the module object of the function you're calling -- that module object's
dictionary is the function's global namespace. Say:

sub_module = __import__(which_one_this_time)
vars(sub_module).update(which_dict_this_time)
print sub_module.the_function(23)

There are other ways, but few are as direct as this one.
Alex
Jul 18 '05 #4
Alex Martelli wrote:
David Rysdam <dr*****@ll.mit.edu> wrote:
...

What I want to do is be able to run multiple scripts that use the same
global variable and function names but be able to have my master script
define those variables and functions programmatically. Can I do that
with the rexec sandbox stuff? Or is rexec more about keeping the
exec()'d code from doing things than specifying precisely what it can do?

rexec has been removed because it did not offer the security it
purported to offer (it was about keeping code from doing bad things, but
it reallly didn't), sigh.

You can do what you want for example by setting the values you want in
the module object of the function you're calling -- that module object's
dictionary is the function's global namespace. Say:

sub_module = __import__(which_one_this_time)
vars(sub_module).update(which_dict_this_time)
print sub_module.the_function(23)

There are other ways, but few are as direct as this one.
Alex


Oh wow, of course! I can set properties on the modules themselves. I'm
going to have to rethink what I'm doing and mess with that a bit, I'm
sure I'll have questions and problems later. Thanks!
Jul 18 '05 #5
David Rysdam <dr*****@ll.mit.edu> wrote:
...
sub_module = __import__(which_one_this_time)
vars(sub_module).update(which_dict_this_time)
print sub_module.the_function(23)
... Oh wow, of course! I can set properties on the modules themselves. I'm
going to have to rethink what I'm doing and mess with that a bit, I'm
sure I'll have questions and problems later. Thanks!


You're welcome! Yes, since your modules are not being used for other
purposes except running the scriptlets you're controlling, changing
those modules' global variables should be safe enough in your case.
Alex
Jul 18 '05 #6
Alex Martelli wrote:
David Rysdam <dr*****@ll.mit.edu> wrote:
...
sub_module = __import__(which_one_this_time)
vars(sub_module).update(which_dict_this_time)
print sub_module.the_function(23)


...
Oh wow, of course! I can set properties on the modules themselves. I'm
going to have to rethink what I'm doing and mess with that a bit, I'm
sure I'll have questions and problems later. Thanks!

You're welcome! Yes, since your modules are not being used for other
purposes except running the scriptlets you're controlling, changing
those modules' global variables should be safe enough in your case.
Alex


OK, dumb question #1:

Why do this:

sub_module = __import__(which_module_this_time)
vars(sub_module).update(which_dict_this_time)

When I could just do this:

__import__(which_module_this_time, which_dict_this_time)

?
Jul 18 '05 #7
David Rysdam <dr*****@ll.mit.edu> wrote:
...
OK, dumb question #1:

Why do this:

sub_module = __import__(which_module_this_time)
vars(sub_module).update(which_dict_this_time)

When I could just do this:

__import__(which_module_this_time, which_dict_this_time)

?


You can do whatever you wish, but what makes you think these constructs
have similar effects? Quoting from Python's online docs on __import__,

"""
the standard implementation does not use its locals argument at all,
and uses its globals only to determine the package context of the
import statement
"""

In short, the standard implementation of __import__ does NOT alter in
any way the dict of the module it imports.
Alex
Jul 18 '05 #8
Alex Martelli wrote:
David Rysdam <dr*****@ll.mit.edu> wrote:
...
OK, dumb question #1:

Why do this:

sub_module = __import__(which_module_this_time)
vars(sub_module).update(which_dict_this_time)

When I could just do this:

__import__(which_module_this_time, which_dict_this_time)

?

You can do whatever you wish, but what makes you think these constructs
have similar effects? Quoting from Python's online docs on __import__,

"""
the standard implementation does not use its locals argument at all,
and uses its globals only to determine the package context of the
import statement
"""

In short, the standard implementation of __import__ does NOT alter in
any way the dict of the module it imports.
Alex


Ah, I see.

Your "which_dict_this_time" dictionary, how are you imagining that
working? I was just mapping function name strings to functions
({'logError':logError}), but (long story short) that isn't working how I
want. But shouldn't I be able to define the function right there in the
dictionary itself?

Perhaps this is getting too non-obvious, magical and unmaintainable, though.
Jul 18 '05 #9
David Rysdam wrote:
Alex Martelli wrote:
sub_module = __import__(which_module_this_time)
vars(sub_module).update(which_dict_this_time)


Your "which_dict_this_time" dictionary, how are you imagining that
working? I was just mapping function name strings to functions
({'logError':logError}), but (long story short) that isn't working how
I want. But shouldn't I be able to define the function right there in
the dictionary itself?

Perhaps this would be a bit clearer with more-meaningful names. (Of
course, that's presuming that I'm reading Alex's intent correctly... :) )

std_global_dict = { 'logError': logError, ... }
script_module = __import__('some_script_module')
vars(script_module).update(std_global_dict)

This will have the effect of injecting all of the specified names (in
std_global_dict) into the scriptlet's module, where they can be used as
global variables. (But note that logError(), and other functions put
into std_global_dict, will execute in the context in which they were
defined -- that is, logError is using its own module's globals, not
script_module's globals or std_global_dict.)

Jeff Shannon
Technician/Programmer
Credit International

Jul 18 '05 #10
On Tue, 14 Sep 2004 14:25:04 -0400, David Rysdam <dr*****@ll.mit.edu> wrote:
Alex Martelli wrote:
David Rysdam <dr*****@ll.mit.edu> wrote:
...
OK, dumb question #1:

Why do this:

sub_module = __import__(which_module_this_time)
vars(sub_module).update(which_dict_this_time)

When I could just do this:

__import__(which_module_this_time, which_dict_this_time)

?

You can do whatever you wish, but what makes you think these constructs
have similar effects? Quoting from Python's online docs on __import__,

"""
the standard implementation does not use its locals argument at all,
and uses its globals only to determine the package context of the
import statement
"""

In short, the standard implementation of __import__ does NOT alter in
any way the dict of the module it imports.
Alex


Ah, I see.

Your "which_dict_this_time" dictionary, how are you imagining that
working? I was just mapping function name strings to functions
({'logError':logError}), but (long story short) that isn't working how I
want. But shouldn't I be able to define the function right there in the
dictionary itself?

Perhaps this is getting too non-obvious, magical and unmaintainable, though.


Maybe this will give you some ideas:

Here empty.py is just a single blank text line with a (windows in this case, which
for the heck of it I'll show in binary) EOL:
open('empty.py','rb').read() '\r\n'
import empty When you import, you automatically get some stuff in the module directory dir(empty) ['__builtins__', '__doc__', '__file__', '__name__'] vars(empty).keys() ['__builtins__', '__name__', '__file__', '__doc__']

If you have source defining a function, you can exec the definition in a directory,
which will become what the function sees as its global directory. So,
exec """ ... def foo(a):
... return a+b
... """ in empty.__dict__

It shows up:
dir(empty) ['__builtins__', '__doc__', '__file__', '__name__', 'foo']

since b is retrieved from the global dict, we better put something there.
That happens to be the dict that stores module attributes, so we can:
empty.b = 100
empty.foo(23) 123 empty.b = 200
empty.foo(23) 223
.... as expected.

We can verify that foo's global dict is empty's dict: empty.foo.func_globals is empty.__dict__ True

If you have definitions of functions in source files, you can execfile them
in a similar manner:

First I'll creat a source right here, though I could have done it in an editor open('baz.py','w').write(""" ... def baz(x):
... return 2*b+x
... """)

Verify print '----\n%s----'%open('baz.py').read() ----

def baz(x):
return 2*b+x
----

Use execfile do define it in empty: execfile('baz.py', empty.__dict__)
It shows up: dir(empty) ['__builtins__', '__doc__', '__file__', '__name__', 'b', 'baz', 'foo']

Check b: empty.b 200 empty.baz(44) 444

HTH. Note that exec-ing or execfile-ing untrusted source is not safe.

BTW, if in the same interpreter execution session you import empty from another module,
the updated contents should be visible. E.g.,
open('mimpbaz.py','w').write("""import empty ... """) print '----\n%s----'%open('mimpbaz.py').read() ----
import empty
---- import mimpbaz
dir(mimpbaz) ['__builtins__', '__doc__', '__file__', '__name__', 'empty'] mimpbaz.empty is empty True mimpbaz.empty.b 200 mimpbaz.empty.baz(3056) 3456

recalling that baz did 2*200+3056 3456

Note that the source of empty.py has not changed print '----\n%s----'%open('empty.py').read() ----

---- open('empty.py').read()

'\n'

Of course, it doesn't have to start out empty. The point is
exec and execfile don't save a compiled .pyc for you to make
it faster next time, whereas import does (unless it's prevented
by lack of write privilege or such, I think).

Regards,
Bengt Richter
Jul 18 '05 #11
David Rysdam <dr*****@ll.mit.edu> wrote:
...
sub_module = __import__(which_module_this_time)
vars(sub_module).update(which_dict_this_time)
... Your "which_dict_this_time" dictionary, how are you imagining that
working?
Just like any other dictionary -- maybe I don't get your question...?
I was just mapping function name strings to functions
({'logError':logError}), but (long story short) that isn't working how I
want. But shouldn't I be able to define the function right there in the
dictionary itself?
....because def is a statement and "in the dictionary itself" you can, of
course, only have expressions...? Is this a trick question...?

Perhaps this is getting too non-obvious, magical and unmaintainable, though.


Your questions are definitely anything but obvious to me...
Alex
Jul 18 '05 #12
Bengt Richter wrote:
On Tue, 14 Sep 2004 14:25:04 -0400, David Rysdam <dr*****@ll.mit.edu> wrote:

Alex Martelli wrote:
David Rysdam <dr*****@ll.mit.edu> wrote:
...
OK, dumb question #1:

Why do this:

sub_module = __import__(which_module_this_time)
vars(sub_module).update(which_dict_this_time )

When I could just do this:

__import__(which_module_this_time, which_dict_this_time)

?
You can do whatever you wish, but what makes you think these constructs
have similar effects? Quoting from Python's online docs on __import__,

"""
the standard implementation does not use its locals argument at all,
and uses its globals only to determine the package context of the
import statement
"""

In short, the standard implementation of __import__ does NOT alter in
any way the dict of the module it imports.
Alex


Ah, I see.

Your "which_dict_this_time" dictionary, how are you imagining that
working? I was just mapping function name strings to functions
({'logError':logError}), but (long story short) that isn't working how I
want. But shouldn't I be able to define the function right there in the
dictionary itself?

Perhaps this is getting too non-obvious, magical and unmaintainable, though.

Maybe this will give you some ideas:


Aha, yes indeed this gives me ideas. Very excellent tutorial, I've
saved it for when I manage to confuse myself again later. I think I
know just how to do what I want to do now, though I'm beginning to
question the wisdom of providing the feature in question at all. But if
I'm going to, it should be right, so I still thank you.
Jul 18 '05 #13
David Rysdam wrote:

Aha, yes indeed this gives me ideas. Very excellent tutorial, I've
saved it for when I manage to confuse myself again later. I think I
know just how to do what I want to do now, though I'm beginning to
question the wisdom of providing the feature in question at all. But if
I'm going to, it should be right, so I still thank you.


I knew I was doing this the wrong way and I've just realized what the
Right Way is: I should just use objects instead of trying to manipulate
dictionaries. When I make a new version of the "API", I just create a
new class to inherit from the previous version.

I'm a bit concerned that it took me so long to realize this...
Jul 18 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Kepes Krisztian | last post by:
Hi ! How to access my module global vars ? Some applications I want to declare global vars (constants). But in the module I cannot access them: DEF_X=120
2
by: Claire | last post by:
hi, i use vars() or dir() to get variables. I use them in a def block, so i get variables of that block. How can i get variables from the namespace __main__ ? I use python in interactive mode and...
6
by: flamesrock | last post by:
ok, so to my knowledge, object oriented means splitting something into the simplest number of parts and going from there. But the question is- when is it enough? For example I have the following...
4
by: Kenny Ashton | last post by:
Hello gurus Can I ask you opions on the best compromise for storing Access Ado connection strings in a IIS4 standard ASP environment. For any method I use, there seems to be an article somewhere...
11
by: Capstar | last post by:
Hi, I am working on an application, which will run embedded without an OS. The app is build up out of a couple of well defined parts. At first I wanted to keep those parts seperated and use...
10
by: Kleenex | last post by:
Reason: I am working on an embedded project which has very limited memory (under 512 bytes, 60 or so of which is stack space), which translates into limited stack space. In order to save on stack...
1
by: Konstantinos Pachopoulos | last post by:
Hi, i had posted earlier for not being able to declare global vars. No i followed the suggestions and created a class, but still the vars do not seem to have a global scope. I have tried pretty...
4
by: pcaisse | last post by:
I'm having issues sharing global variables with Explorer. This problem probably has a simple answer (as with most newbie questions). The script.pl file: #!/usr/bin/perl -w use strict; use...
19
RMWChaos
by: RMWChaos | last post by:
Previously, I had used independent JSON lists in my code, where the lists were part of separate scripts. Because this method did not support reuse of a script without modification, I decided to...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.