[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