Using Mel in a python loop is not returning the correct result

Hi Everyone, quick question. Im trying to use eval() inside a python loop and it doesn’t return the correct result when called inside a function. Does anyone have any ideas?


import maya.mel as mel
import maya.cmds as cmds


#correct output
for i in range(0,3):
    m = mel.eval('$i = `python i`;')     
    print ("Correct: py=" + str(i) + " mel=" + str(m))

#incorrect output
def fn():
    for i in range(0,3):
        m = mel.eval('$i = `python i`;')     
        print ("Incorrect: py=" + str(i) + " mel=" + str(m))
fn()

for context Im trying to loop through all the takes inside an FBX file, then perform some other actions. Unfortunately the function causes mel.eval() to fail.


import maya.mel as mel
import maya.cmds as cmds

def fn():
    importDir = "C:\my.fbx"  
    mel.eval('FBXRead -f `python "importDir"`')
    takes = mel.eval('FBXGetTakeCount')
        
    for i in range(1,takes):
        print mel.eval('FBXGetTakeName `python "i"`')
        
fn()  

Ugh… finally got it.


import maya.mel as mel
import maya.cmds as cmds

def fn():
    importDir = "C:\my.fbx"  
    mel.eval('FBXRead -f `python "importDir"`')
    takes = mel.eval('FBXGetTakeCount')
        
    for i in range(1,takes):
        print mel.eval('FBXGetTakeName ' + str(i))
        
fn()

just curious why you’re executing python in the mel() call at all? just concatenate the mel command string in python

Or you can avoid mel.eval altogether.


import maya.cmds as cmds

def fn():
    importDir = "C:\my.fbx"  
    cmds.FBXRead('-f', importDir)
    takes = cmds.FBXGetTakeCount()
        
    for i in xrange(1, takes + 1):
        print(cmds.FBXGetTakeName(i))
        
fn()

There is also pymel’s mel syntax which I tend to prefer, because you can use keywords arguments instead of string flags.


import pymel.core as pm
def fn():
    importDir = "C:\my.fbx"  
    pm.mel.FBXRead(f=importDir)
    takes = pm.mel.FBXGetTakeCount()

    for i in xrange(1, takes + 1):
        print(pm.mel.FBXGetTakeName(i))
        
fn()

Also, you have a bit of a bug in your range(1, takes), you need to add one to the take count, as range(1, 1) returns an empty list.
And you should probably be careful with your importDir = “C:\my.fbx”, you’re not properly escaping your backslash.

Well what do you know! I had no idea I could do that with pymel. I do very little python scripting so it was more of a trial/error method.

Thanks! This is very helpful