Comment 1 for bug 800861

Revision history for this message
David Rose (droklaunchpad) wrote :

Unlike some other languages, Python's lambda syntax doesn't perform a full closure on its parameters automatically. This means that when you use a syntax like "lambda: func(key)", the variable reference "key" does not retain the value of the variable at the time you bound it, but rather looks up the variable "key" from the *calling* namespace. This is almost never what you intended. To force Python to bind in a variable reference, you pass it in as a default parameter, like this: "lambda key = key: func(key)". This is a bit of a hairy kludge, but it's the Python way.

You can also use use Panda's Functor class to do this for you. "from direct.showbase.PythonUtil import Functor", then pass "Functor(func, key)", instead of a lambda object, to the command parameter.

I've never seen functools.partial before, but it apparently is meant to do the same thing as our Functor class. Unfortunately, it doesn't define a __name__ member for some reason (unlike almost every other kind of Python object), so it causes a crash in the FunctionInterval code which assumes the function object you pass does have a __name__ member. I've just committed a workaround to FunctionInterval to allow it to work without this.