[python] evalDeferred calling self.function


#1

Hi guys.

I’m working on refactoring a small mel script into python.
In order to work, some variables have to be declared globally.

For now, let’s say I have something like that :

cSel = []

def snapOnSurface( mode='' ):
    global cSel
    cSel = mc.ls(sl=True)
    do_snap()

def doSnap():
    print cSel[0]
    mc.evalDeferred("scriptJobNum = mc.scriptJob(runOnce=True, ac=['%s.outMesh', doSnap])" %cSel[0] )

Now, as I understood, it is not really elegant to have global variables used like that.
So I tried to put all my code into a class, and it gives me something like that:

class SnapOnMesh():
    def __init__(self):
        self.cSel = []

    def snapOnSurface( self, mode='' ):
        self.cSel = mc.ls(sl=True)
        self.doSnap()

    def doSnap(self):
        print self.cSel
        mc.evalDeferred("self.scriptJobNum = mc.scriptJob(runOnce=True, ac=['%s.outMesh', self.doSnap] )" %self.cSel[0])

If I import the class and try to run it like that :
class_SnapOnMesh = snapOnMesh.SnapOnMesh()
class_SnapOnMesh.snapOnSurface(mode=‘start’)

I get the following error : NameError: name ‘self’ is not defined.
It is apparently caused by the way I call for my function inside the mc.evalDeferred command (I don’t get the error if I just run the mc.scriptJob command, bor in order for my code to work, I have to use the evalDeferred command).

Is there some syntax I’m misusing somewhere ?

Thanks in adance,

CHeers,

Lisa


#2

Strings are not your friends with python.You can create a method in the class named startScriptJob(self) and do:

evalDeferred(self.startScriptJob)

This should work.


#3

doing things with magic strings should really be avoided everywhere possible. Define a method in the same class as your using the evalDefered, and you can pass it in as a function object, or if you need arguments, you can use a lambda to create a quick temporary method to pass in, that runs what you need.