473,698 Members | 2,132 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

modifying locals


I would like to write a function to write variables to a file and modify a
few 'counters'. This is to replace multiple instances of identical code in a
module I am writing.

This is my approach:

def write_vars(D):
""" pass D=locals() to this function... """
for key in D.keys():
exec("%s = %s" % (key,D[key]))

outfile.write(. ..)
numcount += 1
do this, do that...

the issue is that at the end, I want to return outfile, numcount, etc... but
I would prefer to not return them explicitly, that is, I would just like
that the modified values are reflected in the script. How do I do this?
Using global? But that seems a bit dangerous since I am using exec.

Bringing up another matter... is there a better way to do this that doesn't
use exec?

Thanks!

--
View this message in context: http://www.nabble.com/modifying-loca...p20255725.html
Sent from the Python - python-list mailing list archive at Nabble.com.

Oct 30 '08 #1
6 1781
On Thu, 30 Oct 2008 14:21:01 -0700, John [H2O] wrote:
I would like to write a function to write variables to a file and modify
a few 'counters'.
Are you talking about a function to generate Python source code?

This is to replace multiple instances of identical
code in a module I am writing.

Surely the right way to do this is to factor out the identical code into
a function, and then call the function.

This is my approach:

def write_vars(D):
""" pass D=locals() to this function... """
for key in D.keys():
exec("%s = %s" % (key,D[key]))
That would be better written as:

for key,item in D.iteritems():
exec "%s = %s" % (key, item)

exec is a statement, not a function, and doesn't require brackets.

outfile.write(. ..)
numcount += 1
do this, do that...

the issue is that at the end, I want to return outfile, numcount, etc...
but I would prefer to not return them explicitly, that is, I would just
like that the modified values are reflected in the script. How do I do
this? Using global? But that seems a bit dangerous since I am using
exec.
What you are actually trying to do is unclear to me. Perhaps you could
try explaining better with a more concrete example?

I wounder whether this might be what you are after?

# start of script (untested)
counter = 0 # define a counter in the module scope (global)
filename = 'foo.txt'

def make_vars():
global outfile, numcount # force names to be in module scope
outfile = open(filename, 'w')
numcount = 99

try:
numcount
except NameError:
print "numcount doesn't exist yet, making it"
make_vars()

print numcount
# end script
But of course the above can be written much more concisely as:

# start of script (untested)
counter = 0
filename = 'foo.txt'
outfile = open(filename, 'w')
numcount = 99
print numcount
# end script

so I'm not really sure you're trying to do what you seem to be doing.


--
Steven
Oct 30 '08 #2

Steven D'Aprano-7 wrote:
>
What you are actually trying to do is unclear to me. Perhaps you could
try explaining better with a more concrete example?

--
Steven
--
Actually, maybe a LACK of an example would make it simpler. What I'm after
is a function, to which I can pass a dictionary defined from locals(), then
in the function I would modify some of the variables from the dictionary.
But I want the modifications to be 'seen' by the method that called the
function without passing them back via return.

Ideally, I would prefer not to use global, as I think (due to other problem
in my scripting) this might cause problems.

Currently I these two possibilities:

def myFunction(D):
for key,item in D.iteritems():
exec "%s = %s" % (key, item)

modify a few of the elements...
return locals()

then,
#script
D=locals()
D=myFunction(D)
for key,item in D.iteritems():
exec "%s = %s" % (key,item)
OR:

def myFunction(D):
for key,item in D.iteritems():
exec "%s = %s" % (key, item)

modify a few of the elements...
declare global on the elements modified...
then,
#script
D=locals()
myFunction(D)

As a point.. I thought I read somewhere that D.iteritems wasn't going to be
available in Python3 so I've been trying to 'ween' myself from it.

Thanks!
--
View this message in context: http://www.nabble.com/modifying-loca...p20257394.html
Sent from the Python - python-list mailing list archive at Nabble.com.

Oct 30 '08 #3
On Thu, 30 Oct 2008 16:19:11 -0700, John [H2O] wrote:
Steven D'Aprano-7 wrote:
>>
What you are actually trying to do is unclear to me. Perhaps you could
try explaining better with a more concrete example?
Actually, maybe a LACK of an example would make it simpler. What I'm
after is a function, to which I can pass a dictionary defined from
locals(), then in the function I would modify some of the variables from
the dictionary. But I want the modifications to be 'seen' by the method
that called the function without passing them back via return.
Why do you want that? That is typically something you don't want,
because it can make the program hard to understand very easily. Python
has no dynamic scoping and if you "hack" this into you program the
function call has very unexpected and surprising side effects.

So I ask for the use case too. What problem are you trying to solve?
There might be a better way than executing strings as code and trying to
inject names into the callers namespace.

Ciao,
Marc 'BlackJack' Rintsch
Oct 31 '08 #4
On Fri, 31 Oct 2008 07:10:05 +0100, Tino Wildenhain wrote:
Also, locals() already returns a dict, no need for the exec trickery.
You can just modify it:
>>locals()["foo"]="bar"
>>foo
'bar'
That is incorrect. People often try modifying locals() in the global
scope, and then get bitten when it doesn't work in a function or class.

>>def foo():
.... x = 1
.... locals()['y'] = 2
.... y
....
>>foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in foo
NameError: global name 'y' is not defined

You cannot modify locals() and have it work. The fact that it happens to
work when locals() == globals() is probably an accident.

--
Steven
Oct 31 '08 #5
On Oct 30, 9:21*pm, "John [H2O]" <washa...@gmail .comwrote:
I would like to write a function to write variables to a file and modify a
few 'counters'. This is to replace multiple instances of identical code in a
module I am writing.

This is my approach:

def write_vars(D):
* * """ pass D=locals() to this function... """
* * for key in D.keys():
* * * * exec("%s = %s" % (key,D[key]))

* * outfile.write(. ..)
* * numcount += 1
* * do this, do that...

the issue is that at the end, I want to return outfile, numcount, etc... but
I would prefer to not return them explicitly, that is, I would just like
that the modified values are reflected in the script. How do I do this?
Using global? But that seems a bit dangerous since I am using exec.

Bringing up another matter... is there a better way to do this that doesn't
use exec?
What you're trying to do is hard to achieve but there's a reason for
that: it's a bad idea as it makes code really difficult to maintain.

You may want to define a class to contain all those variables that
need to be changed together:

class MyVars(object):
def __init__(self, outfile, numcount, ...):
self.outfile = outfile
self.numcount = numcount
def write_and_do_st uff(self):
self.outfile.wr ite(...)
self.numcount += 1
# do this, do that...

Then you can use this in your functions:

def myfunction():
vars = MyVars(open('my .log', w), 0, ...)
# Do some stuff
vars.write_and_ do_stuff()
# Do more stuff

You may even consider making some of those functions into methods of
the class.

--
Arnaud

Oct 31 '08 #6
On 2008-10-31 09:08, Tino Wildenhain wrote:
Hi,

Steven D'Aprano wrote:
>On Fri, 31 Oct 2008 07:10:05 +0100, Tino Wildenhain wrote:
>>Also, locals() already returns a dict, no need for the exec trickery.
You can just modify it:

>>locals()["foo"]="bar"
>>foo
'bar'

That is incorrect. People often try modifying locals() in the global
scope, and then get bitten when it doesn't work in a function or class.
>>
>>>>def foo():
... x = 1
... locals()['y'] = 2
... y
...
>>>>foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in foo
NameError: global name 'y' is not defined

You cannot modify locals() and have it work. The fact that it happens
to work when locals() == globals() is probably an accident.

Ah thats interesting. I would not know because I usually avoid
such ugly hacks :-)
It doesn't even work for already defined local variables:
>>def foo():
.... x = 1
.... locals()['x'] = 2
.... print x
....
>>foo()
1

The reason is that locals are copied in to a C array
when entering a function. Manipulations are then
done using the LOAD_FAST, STORE_FAST VM opcodes.

The locals() dictionary only shadows these locals: it copies
the current values from the C array into the frame's
f_locals dictionary and then returns the dictionary.

This also works the other way around, but only in very
cases:

* when running "from xyz import *"
* when running code using "exec"

globals() on the other hand usually refers to a module
namespace dictionary, for which there are no such
optimizations..

I don't know of any way to insert locals modified in
a calling stack frame... but then again: why would you
want to do this anyway ?

--
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Source (#1, Oct 31 2008)
>>Python/Zope Consulting and Support ... http://www.egenix.com/
mxODBC.Zope.D atabase.Adapter ... http://zope.egenix.com/
mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
_______________ _______________ _______________ _______________ ____________

:::: Try mxODBC.Zope.DA for Windows,Linux,S olaris,MacOSX for free ! ::::
eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48
D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
Registered at Amtsgericht Duesseldorf: HRB 46611
Oct 31 '08 #7

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

Similar topics

2
2387
by: Giles Brown | last post by:
I do not understand why the following code produces NameError: name 'FirstClass' is not defined when both a global and local dict are passed into exec, but not when only a global dict is passed in. I seek enlightenment! Thanks, Giles Brown
15
2493
by: Paul Paterson | last post by:
I am trying to find a way to mimic by-reference argument passing for immutables in Python. I need to do this because I am writing an automated VB to Python converter. Here's an example of the VB code: Sub Change(ByVal x, ByRef y) x = x+1 y = y+1 End Sub
2
4186
by: tedsuzman | last post by:
----- def f(): ret = 2 exec "ret += 10" return ret print f() ----- The above prints '12', as expected. However,
6
1499
by: Harald Armin Massa | last post by:
I use locals() for conveniently "filling out" SQL-Statements: def updData(id, surename): sql="""update fisch set surename=%(surename)s where id=%(id)s""" cs.execute(sql, locals())
45
2667
by: It's me | last post by:
I am new to the Python language. How do I do something like this: I know that a = 3 y = "a" print eval(y)
1
1573
by: Paolo Pantaleo | last post by:
Hi this exaple: def lcl(): n=1 x=locals() x=100 print "n in lcl() is:" +str(n) #This will say Name error
2
3103
by: xml0x1a | last post by:
How do I use exec? Python 2.4.3 ---- from math import * G = 1 def d(): L = 1 exec "def f(x): return L + log(G) " in globals(), locals() f(1)
2
2961
by: =?iso-8859-1?B?QW5kcuk=?= | last post by:
I want to give a user the possibility of "restarting" an interactive session, by removing all the objects defined by her since the beginning. The way I make this possible is by having a "function" that can be called during the interactive session using locals() as an argument, as follows: restart(locals()) It works. However, I would like to make this "friendlier", i.e. requiring the user to simply type
0
889
by: Steve Holden | last post by:
John wrote: Note that this code will likely fail to execute if D is some object whose str() method does not return a valid Python expression. Return them as a tuple, using an unpacking assignment to bind the different elements to different names. It's not really obvious why you are trying to replicate the caller's namespace inside this function. Perhaps you could explain a little more what you are trying to achieve.
0
8672
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8600
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9156
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9021
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8860
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6518
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4361
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3038
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2323
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.