execfile() and locals()
Hello all, The documentation on execfile() and locals() makes it clear that code executed from execfile() can not modify local variables in the function from wich execfile() was called. Two questions about this: 1. Is there some way to circumvent this limitation (apart from explicitly copying variables to/from a dictionary passed as locals to execfile()) ? 2. (for experts only I guess) I'd like to understand *why* this is the case. TIA, -- FA There are three of them, and Alleline. -- http://mail.python.org/mailman/listinfo/python-list
Re: execfile() and locals()
On Sun, Aug 15, 2010 at 11:24:25PM +, Steven D'Aprano wrote: > On Sun, 15 Aug 2010 23:21:51 +0200, fons wrote: > > > The documentation on execfile() and locals() makes it clear that code > > executed from execfile() can not modify local variables in the function > > from wich execfile() was called. Two questions about this: > > > > 1. Is there some way to circumvent this limitation (apart from > > explicitly copying variables to/from a dictionary passed as locals to > > execfile()) ? > > Chances are very good that if you're using exec or execfile inside a > function, you probably don't need to. In this case that would probably be true (see below). > As an optimization, local variables don't live inside a dict namespace. > The space for those locals is allocated at compile time, and locals() > returns a copy of the variables in a dict. > > However, the action of exec is a little more subtle, and mysterious, as > seen by this example in Python 3.1: > > >>> def f(): > ... x = 1 > ... print(locals()) > ... exec("x=2; y=0") > ... print(locals()) > ... > >>> > >>> f() > {'x': 1} > {'y': 0, 'x': 1} > > This shows that exec was able to create a new local variable, but not > modify an existing one -- this is completely unintuitive to me. I would > have guessed the opposite. And worse: > > >>> f.__code__.co_varnames > ('x',) > >>> f.__code__.co_nlocals > 1 > > So where does the newly-created local `y` live, if not in a dict > namespace and not in the usual variable slots? > > Curiouser and curiouser... Indeed... and I tried your example also in 2.6, and there it 'just works'. I've been reading a bit on execfile() and friends on various locations on the web, and there seems to be some controversy about it. One poster even wrote 'If you need execfile() you have a design problem'. I don't agree - in this case I use an interpreted language exactly to be able to do such things as made possible by execfile(). The application is a GUI one used to control electronic musical instruments and audio processors in a 'live performance' situation. Its main window shows a collection of buttons, rotary controls, sliders, etc., which trigger things when used. For example, clicking on a button could start a timed sequence of actions, each action being e.g. a message sent to a synthesis program or an audio processor, and/or some changes to the GUI itself. Such a sequence could be quite complex, defining it may require loops and conditions, or even interaction with other sequences, so the natural way is to define it as code and not as data. Users of the system are assumed to know basic Python, without being experts or expected to understand things such as the ones we are discussing. Sequences will run for some time, many of them can run at the same time, so each of them will be executed in a separate thread if required. A basic requirement for the system is that all actions can be redefined while the program is running, hence the need for execfile() or something similar. Shift-click on a GUI item presents a menu with options to modify its actions, one of them is to edit the file defining the code associated with the item. Now there are two ways to use execfile() or equivalent: 1. Actually execute the file when e.g. a button is clicked. 2. Execute it when the action is defined (i.e. when the user has finished editing the file). In the case the file should define a function which will be executed when triggered. I'll probably use the second way - the function will be precompiled, and most errors will show up before it is actually executed. Ciao, -- FA There are three of them, and Alleline. -- http://mail.python.org/mailman/listinfo/python-list
PyCObject_FromVoidPtr etc.
Hello all, Upgrading to 3.2 has provided some sort of cold shower. I have hundreds of extensions that fail to install due to PyCObject_FromVoidPtr() and PyCObject_AsVoidPtr() not longer being available, and I'm looking for a (hopefully) simple solution. In all cases, these are extensions that create an instance of a C++ class which is purely a 'slave' to the corresponding instance of a Python class. They all follow a pattern illustrated by the following code: --- #include "class_XX.h" extern "C" void destroy (void *object) { Class_XX *C; C = (Class_XX *) object; delete P; } extern "C" PyObject* create (PyObject *self, PyObject *args) { Class_XX *C; PyObject *P; int a, b; if (! PyArg_ParseTuple(args, "(Oii)", &P, &a, &b)) return NULL; C = new Class_XX (P, a, b); return PyCObject_FromVoidPtr((void *) C, destroy); } extern "C" PyObject* method_1 (PyObject *self, PyObject *args) { Class_XX *J; PyObject *P; int x, y; if (! PyArg_ParseTuple(args, "(Oii)", &P, &x, &y)) return NULL; C = (Class_XX *) PyCObject_AsVoidPtr(P); P = Py_BuildValue ("(i)", C->method_1 (x, y)); Py_INCREF (P); return P; } ... -- The C++ object stores a pointer to its Python equivalent (not needed in most cases, only if there would be callbacks) and the Python object stores a PyCObject corresponding to its C++ slave and uses this to call its methods. In no case there is any need of the C++ objects being visible anywhere else, let alone in other extensions. Is there a way to keep things (almost) as simple as this using the 'Capsules' ?? I do understand the advantage of having such a mechanism, but in this case it's sort of overkill... TIA, -- FA -- http://mail.python.org/mailman/listinfo/python-list
Callback mysteries
Hello all, I wonder if someone could explain some of the following. (Python 3.2) I have a class which has a method called 'callback()'. An instance of this class calls a C extension which then calls back into Python. In all cases below, two arguments are passed to the C code and end up in PyObject *object; PyObject *method; The original solution was: P: self -> object, "callback" -> method C: PyObject_CallMethodObjArgs(object, method, 0); and this works nicely. Just out of academic interest, I was wondering if the run-time lookup of 'callback' could be avoided. My first attempt was: P: self -> object, classname.callback -> method C: PyObject_CallFunctionObjArgs(method, object, 0); and this also works, I'm just not sure it's kosher. Now in theory 'self.callback' should contain all info that is required (or not ?). So I also tried: P: self -> object, self.callback -> method C: PyObject_CallFunctionObjArgs(method, PyMethod_Self(method), 0) which fails, P: self -> object, self.callback -> method C: PyObject_CallFunctionObjArgs(PyMethod_Function(method), PyMethod_Self(method), 0); which also fails. And indeed the value returned by PyMethod_Self() is not equal to the value of object (= self). In fact it seems not to depend on the calling instance at all. Do I misunderstand what PyMethod_Self() is supposed to return ? I also tried P: self -> object, self.callback -> method C: PyObject_CallObject(method, 0); which also fails. Any comments that help me understand these things will be appreciated ! Ciao, -- FA -- http://mail.python.org/mailman/listinfo/python-list
Re: why memoizing is faster
On Thu, Mar 24, 2011 at 08:12:22PM -0400, Terry Reedy wrote: > The irony of this is that memoizing 'recursive' functions with a > decorator depends on the fact the Python does not have truly recursive > functions. A function cannot call itself directly. I wonder what exactly is meant by that last sentence: * It doesn't happen (since the function name is evaluated to find the function to be called, as you explained). or * Even if a variable pointing directly to the function were provided (as a global or function argument), calling it is not supposed to work (for some reason). ?? Ciao, -- FA -- http://mail.python.org/mailman/listinfo/python-list
Re: Guido rethinking removal of cmp from sort method
On Mon, Mar 28, 2011 at 11:06:20AM +0200, Antoon Pardon wrote: > Asking for *real-world* uses is just how the python community smothers > requests. It's quite a common strategy, I've seen it used in many contexts. Which doesn't make it any more acceptable of course. > Should someone come with a use case, I expect the following > to happenr: One will go over the case with magnifying glasses in > search for any possible way in which it could be rewritten so as not > to need the cmp anyway. This will probably not be a big problem because > the person with the use case will probably have given a simplified example > to explain the overal picture. However most people responding will > ingnore the overal picture and focus on details that may very well work > on the simplified example but may not in the specific real-world case. > But since going over all details to argue the case will be too time > consuming, in the end the person with the use case will simply fail to > convince. An accurate description of the process. > Forcing people to use a key-function, will produce cases where python > will ask for more memory and take longer to sort, than allowing to provide > a cmp function. This for the simple reason that for some order-functions, > the only way to write a key-function will be to write a specific class, > that will implement the order with the same kind of code that otherwise > would have been put in the cmp function, making the trade off: memory use > vs speed no longer a trade off. If cmp_to_key() would do some (probably impossible) magic - factoring the user's cmp() into a non-trivial key mapping and a simpler and more efficient compare - then it would make sense. But it doesn't do such a thing. The 'key' it uses is just a copy, and the compare that will be used finally is just the user's one. Nothing gained, just overhead added. > If the existance alone of such cases isn't enough to reverse the decision > about the cmp-argument of the sort-method. My guess is that nothing will. Sadly enough, that is probably a good guess. Ciao, -- FA -- http://mail.python.org/mailman/listinfo/python-list
Re: FBI wants public help solving encrypted notes from murder mystery
On Wed, Mar 30, 2011 at 01:25:54PM -0700, Joe Snodgrass wrote: > For larger images of the notes go here. [LINK] [LINK] ??? -- FA -- http://mail.python.org/mailman/listinfo/python-list