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? 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
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?
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
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!
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
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)
?
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
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.
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
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
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
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.
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... This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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,...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
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...
|
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...
|
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
|
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...
| |