import maya.cmds as mc
def showStuff (stuff):
print "You've given me %s!" % stuff
stuffList = ["an apple", "a pear", "a pickle"]
mc.window("Stuff to Give", w=300, h=200)
cl = columnLayout()
for item in stuffList:
mc.button(l=item, c=lambda x, i=item:showStuff(i))
Look, ma...no lambda factory! :) Here's my guess as to why this works when it doesn't work to put the variable "inside" the lambda...
By stuffing a variable into the function/method call inside the lambda function, it appears that the value of the variable isn't retrieved until the lambda function is executed. For a variable defined by a loop, this means that the variable value is the same as it was during the last iteration through the loop.
However, by taking a variable and assigning it as the default for one of the lambda's arguments, the value assigned to that variable is retrieved and stored in the lambda function definition. When called by Maya when the appropriate GUI element is used, the lambda function already has that value, and knows to pass it as the default for the appropriate argument. Because no other data is passed to replace it, it can be used reliably inside the function as part of the real function call we want to make.
The only thing to keep in mind when using this technique is the extra data that Maya passes on its own, which is caught (and promptly ignored) in the example above by the
Clean and simple. Me likey.