473,387 Members | 1,585 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,387 software developers and data experts.

Changing behaviour of namespaces

Hi!

This is in Python 2.3.4 under WinXP.

I have a situation where I think changing the behaviour of a namespace
would be very nice. The goal is to be able to run a python file from
another in a separate namespace in such a way that a NameError is not
raised if a non-existing variable is used in the file. The file that I
want to run is taken out of context, and some needed variables may be
missing that are normally there when used in the intended context. OK!
When I run it out of context, I do not want the execution to stop
half-way through the file based on NameErrors, instead a predefined
dummy variable should be used. The question is: Can I achieve that?

Google didn't give me much, so I experimented a bit: First, I created a
dummy object, which is meant to be used when a variable is missing:

class dummyClass(object):
pass
dummyObject = dummyClass()

The actual dummy object is supposed to be a bit more complicated than
that. The next step was to subclass dict:

class forgivingDict(dict):
def __init__(self,*args,**kwargs):
dict.__init__(self,*args,**kwargs)
def __getitem__(self,key):
print ' Getting', key
try:
return dict.__getitem__(self,key)
except KeyError:
return dummyObject
def __setitem__(self,key,value):
print ' Setting', key, 'to', value
dict.__setitem__(self,key,value)
def __contains__(self,item):
return True
def __repr__(self):
return 'forgivingDict(%s)' % (dict.__repr__(self),)

Then I tried to execute a file using a forgivingDict() as namespace:

ns = forgivingDict()
execfile(filePath, ns)

A file containing the following passes perfectly OK:

a = 0
b = a

But a file containing the following produces a NameError:

b = a

The error traceback for the interested:

Traceback (most recent call last):
File "//charm/mikael/My
Documents/Programmering/Python/Tester/voidTest.py", line 130, in ?
execfile('test2.py', ns)
File "test2.py", line 1, in ?
b = a
NameError: name 'a' is not defined

Now, that is exactly what is to expect if ns is a dict(), but I was
hoping that b would have ended up as dummyObject when ns is a
forgivingDict(). One thing: Nothing is printed out when execfile-ing the
files, which means that the methods forgivingDict.__getitem__ and
forgivingDict.__setitem__ are never used. My guess was that the
execution done by execfile uses dict.__getitem__(ns, key) and
dict.__setitem__(ns,key,value) instead of ns[key] and ns[key]=value when
getting and setting variables. That is probably intentional from the
developers and done that way for a good reason.

Alternative test: I've tried to replace __builtin__.dict with my
forgivingDict, slightly modified to make sure that the inheritance still
works, which didn't change anything. So it seams that the execution done
by execfile does *not* use dict.__getitem__(ns, key) and
dict.__setitem__(ns,key,value) after all, but something else. Probably
the original dict is around somewhere else, and execfile uses the
corresponding methods of that.

My approach seems flawed. Any ideas? Can I somehow execute a complete
file even if there are non-existent variables used somewhere? A
try-except around the execfile statement is not an alternative, since
that stops the execution where the error occurs.

Should I perhaps read up on the compiler module? I mean: Using the
compiler module to analyze the content of the file, and based on that
updating my namespace before executing the file.

/MiO
Sep 21 '06 #1
4 1543
Mikael Olofsson wrote:
This is in Python 2.3.4 under WinXP.
To feed an arbitrary mapping object to execfile() you need to upgrade to
Python 2.4.

http://docs.python.org/dev/lib/built...cs.html#l2h-26

Peter
Sep 21 '06 #2
Peter Otten wrote:
To feed an arbitrary mapping object to execfile() you need to upgrade to
Python 2.4.
Thanks! As clear as possible. I will do that.

FYI: I think I managed to achieve what I want in Py2.3 using the
compiler module:

def getNamesFromAstNode(node,varSet):
if node.__class__ in (compiler.ast.Global,compiler.ast.Import):
varSet.union_update(node.names)
if node.__class__ in (compiler.ast.Name,):
varSet.add(node.name)
for subNode in node.getChildNodes():
getNamesFromAstNode(subNode,varSet)

# Get all variable names that are referenced in the file:
varSet = sets.Set()
mainNode = compiler.parseFile(filePath)
getNamesFromAstNode(mainNode,varSet)

# Define a namespace and update it:
ns = {}
for varName in varSet:
ns[varName] = dummyObject

# Execute the file without NameErrors:
execfile(filePath,ns)

Batteries included!

/MiO
Sep 21 '06 #3
Mikael Olofsson wrote:
Peter Otten wrote:
>To feed an arbitrary mapping object to execfile() you need to upgrade to
Python 2.4.

Thanks! As clear as possible. I will do that.

FYI: I think I managed to achieve what I want in Py2.3 using the
compiler module:

def getNamesFromAstNode(node,varSet):
if node.__class__ in (compiler.ast.Global,compiler.ast.Import):
varSet.union_update(node.names)
if node.__class__ in (compiler.ast.Name,):
varSet.add(node.name)
for subNode in node.getChildNodes():
getNamesFromAstNode(subNode,varSet)

# Get all variable names that are referenced in the file:
varSet = sets.Set()
mainNode = compiler.parseFile(filePath)
getNamesFromAstNode(mainNode,varSet)

# Define a namespace and update it:
ns = {}
for varName in varSet:
ns[varName] = dummyObject

# Execute the file without NameErrors:
execfile(filePath,ns)

Batteries included!
Clearly more elegant than:
>>print open(filename).read()
b = a
>>dummy = 42
names = []
while 1:
.... ns = dict((n, dummy) for n in names)
.... try:
.... execfile(filename, ns)
.... except NameError, e:
.... names.append(e[0][6:-16])
.... else:
.... break
....
>>names
['a']

:-)

Peter
Sep 21 '06 #4
Peter Otten wrote:
Clearly more elegant than:

>>>print open(filename).read()
b = a
>>>dummy = 42
names = []
while 1:
... ns = dict((n, dummy) for n in names)
... try:
... execfile(filename, ns)
... except NameError, e:
... names.append(e[0][6:-16])
... else:
... break
...
>>>names
['a']
That sure is nicer. My solution looks like shooting mosquitoes with an
elephant rifle i comparison. Thanks.

/MiO
Sep 21 '06 #5

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

Similar topics

21
by: Blue Ocean | last post by:
Forgive me for asking so many questions so quickly. I am simply asking as they come up unanswered in my book. Can you change namespaces half way through a file? For instance, if you want to...
3
by: CHRISTOF WARLICH | last post by:
Hi, the following few lines of code are showing a quite strange and unexpected behaviour of namespaces that makes me worry wheater I should rely on namespaces in the future at all. The...
11
by: Random | last post by:
I'm confused about the proper use and usefulness of namespaces. I beleive I understand the purpose is so the developer can put classes within namespaces to essentially organize your code. And I...
2
by: junky_fellow | last post by:
guys, If I declare a const variable and then try to change it as follows; const int i=5; i = 10; What would be the behaviour? Should compiler give compilation error or Warning ? Or, would...
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: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
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...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

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.