# Multiple variables for on operator?

Is it possible to have a class method work as same as with a function, where you can put in different parameter for one instance function? Like in my case, where I need to have 8 selection options, each with different naming conventions. This works fine with a function, but I need to execute the operation with a pie menu, so I believe an operator is the only way to go?
I was hoping to have one operator for each option, but have a different variable for each in the pie menu command?

lst = ["YO!", "WAZZAP!?", "HOW'YOU'DOIN!?"]

class Print1(bpy.types.Operator):
bl_idname = "object.print1"
bl_label = "Print 1"

def execute(self, context):
self.printz()
return{"FINISHED"}

@classmethod
def printz(cls, text=lst[0]):

print(text, "What is going on in the kitchen?")

class Print2(bpy.types.Operator):
bl_idname = "object.print2"
bl_label = "Print 2"

def execute(self, context):
Print1.printz(lst[1])
return{"FINISHED"}


In this case, I have one "master" operator that feeds others, but I think there must be a simpler way than have a copy of 7 operators in code, that do almost the same thing? Can it be done as same as with basic functions?

• Given example above, one operator with an index int property. def printz(self): print(lst[self.index]) Pass the different index in your pie menu pie.operator("object.print").index = 0 – batFINGER May 19 '18 at 3:15

Having multiple operators just to call one function with different arguments is not the way I like that, I prefer what @batFINGER suggested in a comment - a single operator that behaves based on passed parameter:

class Print(bpy.types.Operator):
bl_idname = "object.print"
bl_label = "Print"

# this is the parameter
id = bpy.props.IntProperty(default=0)
# it can even be of type StringProperty() and you can pass the message you want

def execute(self, context):
output = ["response 1",
"response 2",
"reposnse 3"]
print(output[self.id])
return {"FINISHED"}


When you call the operator, you pass the parameter:

 bpy.ops.object.print(id=2)
# or inside UI
layout.operator('object.print').id = 2
# prints 'response 3' when pressed

# or like this with multiple params
bpy.ops.object.print(param_1=False, param_2="Foo")
op = layout.operator('object.print')
op.param_1 = False
op.param_2 = "Foo"


Ultimately it depends on what you are doing and whether you have other intentions with the classes. But for simple things like outputting different text this is the way to keep code simple.

Another thing I'd like to mention is to make it explicitly read what it does, ie:

# I have no idea what this prints and have to look it up in code
bpy.ops.object.print(id=2)

# with comment this is better, but falls apart when you change it in operator
# (unless you change all the comments also..)
bpy.ops.object.print(id=2)    # "response 3"

# best (using string param)
bpy.ops.object.print(msg="response 3")


I don't know what exactly you were going for with the class method, but using a function in this case should be equivalent. There is no need for a "master" operator.

from bpy.types import Operator

def printz(index=0):  # "cls" wasn't being used anyway
text = ["A", "B", "C"][index]
print(text)

class Print1(Operator):
bl_idname = "object.print1"
bl_label = "Print 1"

def execute(self, context):
printz()  # index defaults to 0

return {"FINISHED"}

class Print2(Operator):
bl_idname = "object.print2"
bl_label = "Print 2"

def execute(self, context):
printz(1)

return {"FINISHED"}