Search code examples
pythonargumentsinstancemaya

Python- class instance problem (init takes five arguments; only passing two)


I’ve been working on an IK/FK joint matching script, that I managed to finally get working correctly last month. Today start I up Maya, run the script and while the interface loads up, I received the following errors…

This one upon running loading script:

# Error: NameError: file <maya console> line 196: global name 'Fks' is not defined #

and this one upon clicking my ‘select root joint chain’ button:

# Error: NameError: file <maya console> line 1: name 'select_joints_afk' is not defined # 

I’m really new to this so I really don’t understand what exactly is going on

class Create_Selection_Chains(object):

    def __init__(self, name, *args):
        self.Fks = Fks
        self.Ikw = Ikw
        self.Pv = ikpv
        self.name = name
        self.combined_selection = self.Fks+self.Ikw+self.Pv
        print("List created"+self.name)

    def select_joints_afk(self):

        if cmds.ls(selection = True,type=("transform",'nurbsCurve')):
            sel = cmds.ls(sl=True)
            fks = sel
            fkCtrls = cmds.listRelatives(sel, allDescendents=True, type=("transform",'nurbsCurve'))
            Fks = [nurbsCurve for nurbsCurve in fkCtrls if nurbsCurve.startswith('FK') & nurbsCurve.endswith('Ctrl')]
            cmds.textFieldButtonGrp(gtF0, edit = True, tx ='' .join(sel),buttonLabel='IK OK',backgroundColor = (.5,.8,.2))
            del Fks[1]
            del Fks[2]
            Fks.extend(sel)
            print Fks

            return self.Fks 
        else:
            text = cmds.confirmDialog( title='Error', message='Must select joint', button=['OK'], 
                                        defaultButton='Ok', dismissString='No' )

    def select_joints_aikw(self):

        if cmds.ls(selection = True,type=("transform",'nurbsCurve')):

            sel=cmds.ls(selection = True)
            ikwrist = sel
            Ikw = [nurbsCurve for nurbsCurve in ikwrist if nurbsCurve.startswith('IK') & nurbsCurve.endswith('Ctrl')]
            cmds.textFieldButtonGrp(gtF1, edit = True, tx ='' .join(ikwrist),buttonLabel='IK OK',backgroundColor = (.5,.8,.2))
            cmds.select(ikwrist)
            print Ikw
            return self.ikw
        else:
            text = cmds.confirmDialog( title='Error', message='Must select joint', button=['OK'], defaultButton='Ok', 
                                        dismissString='No' )

    def select_joints_ikpv(self):

        if cmds.ls(selection = True,type=("transform",'nurbsCurve')):
            sel = cmds.ls(sl=True)
            ikPvsel = sel
            ikpv = [nurbsCurve for nurbsCurve in ikPvsel if nurbsCurve.startswith('IK') & nurbsCurve.endswith('Ctrl')]
            cmds.textFieldButtonGrp(gtF2, edit = True, tx ='' .join(ikPvsel),buttonLabel='IK OK',backgroundColor = (.5,.8,.2))        
            cmds.select(ikPvsel)
            print ikpv
            return self.ikpv
        else:
            text = cmds.confirmDialog( title='Error', message='Must select joint', button=['OK'], 
                                        defaultButton='Ok', dismissString='No' )

I was told that if I pass the variables into the class when you instantiate it, as long as I pass the required arguments it should run fine, however upon changing

def __init__(self, name, *args):

to

def __init__(self, name, Fks, Ikw, ikpv):

I receive the following message upon loading my script in maya

# Error: TypeError: file <maya console> line 413: __init__() takes at least 5 arguments (2 given) #

line 413 is where I load my instances...:

left_arm_select = Create_Selection_Chains("left arm")

Could someone help me understand what is hapening? because I thought I was passing all my arguments


Solution

  • In short, calling Create_Selection_Chains(...) now requires three more arguments. Why?

    • __init__(self, name, Fks, Ikw, ikpv) requires several positional arguments, i.e. name, Fks, Ikw, ikpv
    • __init__(self, name, *args): requires one positional argument (name) and 0 to many arbitrary arguments (*args).

    Solution: pass in more values at instantiation, e.g. Create_Selection_Chains("left arm", "foo", "bar", "baz")


    Given

    class Create_Selection_Chains(object):
    
        def __init__(self, name, *args):
            self.Fks = Fks
            self.Ikw = Ikw
            self.Pv = ikpv
            self.name = name
            ...
    

    As you have likely discovered, __init__(self, name, *args) doesn't work since args isn't mapped to anything and Fks, Ikw and ikpv are not defined. This will throw an error.

    Code

    Consider the following as one of many options:

    class Create_Selection_Chains:
    
        def __init__(self, name, fks, ikw, ikpv):
            self.name = name
            self.fks = fks
            self.ikw = ikw
            self.pv = ikpv
    
            ...
    

    Finally, pass more values in at instantiation, e.g.:

    left_arm_select = Create_Selection_Chains("left arm", "foo", "bar", "baz")