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.
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.