When a function accepts arguments, the names of those arguments become variables in the function's namespace. Whatever value was passed to the function when it was invoked becomes the value of those variables. Arguments can have default values, which makes them optional. If an argument is omitted, then its default value will be used. The following code defines a function called cap, which will take a number, and make sure it is within an upper and lower limit. The limits default to 0 and 100.
# We first define our function. Notice that we have 3 different arguments. # x, min, and max. The min and the max are set to equal 0 and 100 respectively. def cap(x, min=0, max=100): # Check if x is less than the min, return the min if true. if x < min: return min # Check if x is greater than the max, return the max if true. elif x > max: return max # Return the value if it is within the bounds. else: return x # We can then see the outcome by running our function with a few different parameters. # This will print out a 40, since it is within the bounds. print cap(40) # This will print out "0", since it is less than the min of 0. print cap(-1) # This will print out "100", since it is greater than the max of 100. print cap(150) # This will print out "150", because it uses a max of 200 instead of the default 100. print cap(150, 0, 200)
In Ignition, some complicated script functions are designed to take keyword arguments instead of normal parameters. In the description for those functions, you may see the following info box in this User Manual:
This function accepts keyword arguments.
Arguments can also be specified by keyword instead of by position. In the example above, the only way someone would know that the 200 in the last call to
cap specified the max is by its position. This can lead to hard-to-read function invocations for functions with lots of optional arguments. You can use keyword-style invocation to improve readability. The following code is equivalent to the last line above, using 200 for the
max and the default for the
print cap(150, max=200)
Because we used a keyword to specify that 200 was the
max, we were able to omit the
min argument altogether, using its default. However, using a keyword argument before a non-keyword or positional argument is not allowed.
# This would fail, because the function isn't sure what 150 is being used for. print cap(max=200, 150)
Perhaps one of the most foreign concepts for new Python users is that in Python, functions are first-class objects. This means that functions can be passed around to other functions (this concept is similar to the idea of function pointers in C or C++).
Suppose we wanted a general way to filter a list. Maybe sometimes we want the odd entries, while other times we want even ones. We can define a function called
extract that takes a list and another function, and returns only entries that "pass" through the other function.
# We define a function that checks if the value passed in is odd. def isOdd(num): return num % 2 == 1 # We define a function that checks if the value passed in is even. def isEven(num): return num % 2 == 0 # We define a function that inserts our list into the appropriate function and returns valid values. def extract(filterFunction, list): newList =  for entry in list: if filterFunction(entry): newList.append(entry) return newList # Prints out [0, 2, 4, 6, 8] # Notice that isEven as not invoked, but passed to the filter function. print extract(isEven, range(10))
User Defined Functions can be defined anywhere that a script is used. As stated before, they are useful to run segments of code multiple times without having to repeat it. They are also used extensively in project and shared script modules where multiple functions can be defined in a single script module. Finally, some special Ignition System functions like system.gui.createPopupMenu or the runScript Expression function use functions as arguments.
The concept of scope is very important in all programming, and Python is no exception. Scope defines what names are directly accessible without any qualifiers. Another way to put this is that the scope determines what variables are defined. In Python, a variable is defined at the time that it is assigned. What scope it belongs to is also defined by where the assignment occurs.
# On this line, there is no variable 'x' in scope. doSomeWork() # Now 'x' is defined in our scope, because we've assigned a value to it x = 5 # This will work because x is in scope. print x
When you define a function, that function gets its own scope. Variables that are assigned within that function body will not be available outside of the function.
# x is local to myFunction() because this is where it is defined. def myFunction(): x = 15 print x # This will fail, because x is not available in the outer scope y = x + 10