It is a little tricky but good to understand what is going on here.
First, it is important to understand that functions in python are also objects.
If you define a function like this:
def my_function():
return 2
You can of course directly call this function using my_function()
, but you can also store a refference to it for later use
my_var = my_function
[...]
my_var()
This btw also means you can store functions in to dictionaries and lists, which is also interresting.
So what are we doing with the run part? Checking that docs, we can see that the run-method is defined as follows: run(script, arg1, arg2..
so, we first pass a script (as a string(!) ), and then a arbitrary number of arguments that we can access via the args list in our script.
run("print( args )", "Foo", "Bar")
Will print [“Foo”, “Bar”].
So, simple example would be to pass the refference to an operator, parameter or similiar. For example. lets say we want to destroy an operator after 3 frames.Probably first way of doing that is by passing the string as a arguments:
run( "op('args[0]').destroy()", "path/to/op" )
→ args
But we could also pass the complete operator-object
run( "args[0].destroy()", op("path/to/op") )
Well, now I will tell you something: The destroy method is specific to that operator. So you can save a refference to that method, and call it later!(You can check this easily by running a little script print(op("operator1").destroy == op("operator2").destroy )
→ False
So, lets instead just pass the destroy function as an argument and execute the function that got passed.
run( "args[0]()", op("path/to/op").destroy )
But as you said, there are situations when you have to pass specific information or call a function with specific arguments in a run method. Well, what if I tell you, that you can create a function in a function?
def target_function(argument1, argument2):
argument1.so_domething()
[...]
def my_function():
target_operator = op("foo")
def my_sub_function():
target_function( target_operator, target_operator.par.Bar.eval() )
run ("args[0]()", my_sub_function )
The my_sub_function will be a new one every time and hold the valued you assigned to the parameters until called. Extremly nifty. But you can also define a function in one line, a so called lambda by writing
def my_function():
target_operator = op("foo")
run ("args[0]()", lambda : target_function( target_operator, target_operator.par.Bar.eval() ) )
The concept is called closures and incredible powerfull! If you want to know more check this out for example.
If you ever come in to the situation of using javascript, this concept is all over the place there!