Easy questions from a python beginner
Thomas Jollans
thomas at jollans.com
Fri Jul 23 13:13:45 EDT 2010
On 07/23/2010 12:34 AM, wheres pythonmonks wrote:
> 2. Is there a better way to loopup by id? I'm not very familiar with
> sys.exc_info, but creating the id->name hash each time seems like
> overkill.
I just had the most horrendous idea. Really, looking up objects by ID,
or even swapping two objects, isn't that difficult if you do some C
black magic. Don't try this in front of the kids.
I wrote a little module, called "hell":
Python 3.1.2 (release31-maint, Jul 8 2010, 09:18:08)
[GCC 4.4.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> from hell import swap, getptr
>>> dir
<built-in function dir>
>>> len
<built-in function len>
>>> swap(dir, len)
>>> dir
<built-in function len>
>>> len
<built-in function dir>
>>> a = "this was a"
>>> b = "this was b, hell yeah"
>>> (a, b, id(a), id(b))
('this was a', 'this was b, hell yeah', 32417752, 32418144)
>>> tpl = (a, b, id(a), id(b))
>>> tpl
('this was a', 'this was b, hell yeah', 32417752, 32418144)
>>> swap(a, b)
>>> tpl
('this was b, hell yeah', 'this was a', 32417752, 32418144)
>>> getptr(32417752)
'this was b, hell yeah'
>>>
The code is below. Use it under the terms of the WTFPL version 2.
(http://sam.zoy.org/wtfpl/)
-- Thomas
PS: all of this is a very BAD IDEA. But interesting, in a way.
################# setup.py ############
from distutils.core import setup, Extension
hellmodule = Extension('hell',
sources = ['hellmodule.c'])
setup (name = 'hellmodule',
version = '0.1-apocalypse',
description = 'Functions from hell. Never ever use.',
ext_modules = [hellmodule])
################# hellmodule.c ##############
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject *swap(PyObject *self, PyObject *args);
static PyObject *getptr(PyObject *self, PyObject *args);
static PyMethodDef hell_methods[] = {
{"swap", &swap, METH_VARARGS, ""},
{"getptr", &getptr, METH_VARARGS, ""},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef hell_module = {
PyModuleDef_HEAD_INIT,
"hell", /* module name */
"functions from hell. never use.", /* doc */
-1,
hell_methods
};
PyMODINIT_FUNC
PyInit_hell(void)
{
return PyModule_Create(&hell_module);
}
static PyObject *
swap(PyObject *self, PyObject *args)
{
PyObject *obj1, *obj2;
Py_ssize_t len;
PyObject *temp;
if (!PyArg_ParseTuple(args, "OO", &obj1, &obj2)) {
return NULL;
}
len = obj1->ob_type->tp_basicsize;
if (obj2->ob_type->tp_basicsize != len) {
PyErr_SetString(PyExc_TypeError,
"types have different sizes (incompatible)");
return NULL;
}
temp = PyMem_Malloc(len);
memcpy(temp, obj1, len);
memcpy(obj1, obj2, len);
memcpy(obj2, temp, len);
obj2->ob_refcnt = obj1->ob_refcnt;
obj1->ob_refcnt = temp->ob_refcnt;
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
getptr(PyObject *self, PyObject *args)
{
unsigned long lId;
PyObject *retv;
if (!PyArg_ParseTuple(args, "k", &lId)) {
return NULL;
}
retv = (PyObject*) lId;
Py_INCREF(retv);
return retv;
}
More information about the Python-list
mailing list