[Tutor] constructing semi-arbitrary functions
eryksun
eryksun at gmail.com
Wed Feb 19 22:56:31 CET 2014
On Wed, Feb 19, 2014 at 2:56 PM, "André Walker-Loud
<walksloud at gmail.com>" <walksloud at gmail.com> wrote:
>
> I also happened to get the string-hack to work (which requires
> using global variables).
Functions load unassigned names from the global/builtins scopes, so
there's no need to declare the g* variables global in chisq_mn. Also,
implicit string concatenation and string formatting will make the
definition easier to read, IMO:
def make_chisq_mn(pars, x, y, dy):
global _gx, _gy, _gdy
_gx, _gy, _gdy = x, y, dy
names = ['c_%d' % i for i in xrange(len(pars))]
src = ('def chisq_mn(%(p)s):\n'
' return chisq([%(p)s], _gx, _gy, _gdy)' %
{'p': ', '.join(names)})
print 'funcdef=\n', src
exec src in globals()
You can use a custom dict with exec to avoid contaminating the
module's global namespace:
def make_chisq_mn(pars, x, y, dy):
ns = {'x': x, 'y': y, 'dy': dy, 'chisq': chisq}
names = ['c_%d' % i for i in xrange(len(pars))]
src = ('def chisq_mn(%(p)s):\n'
' return chisq([%(p)s], x, y, dy)' %
{'p': ', '.join(names)})
print 'funcdef=\n', src
exec src in ns
return ns['chisq_mn']
This version of chisq_mn uses the ns dict as its func_globals:
>>> chisq = lambda *a: None # dummy
>>> chisq_mn = make_chisq_mn([1,2,3], 10, 20, 30)
funcdef=
def chisq_mn(c_0, c_1, c_2):
return chisq([c_0, c_1, c_2], x, y, dy)
>>> sorted(chisq_mn.func_globals)
['__builtins__', 'chisq', 'chisq_mn', 'dy', 'x', 'y']
>>> dis.dis(chisq_mn)
2 0 LOAD_GLOBAL 0 (chisq)
3 LOAD_FAST 0 (c_0)
6 LOAD_FAST 1 (c_1)
9 LOAD_FAST 2 (c_2)
12 BUILD_LIST 3
15 LOAD_GLOBAL 1 (x)
18 LOAD_GLOBAL 2 (y)
21 LOAD_GLOBAL 3 (dy)
24 CALL_FUNCTION 4
27 RETURN_VALUE
More information about the Tutor
mailing list