4

I'm writing a custom function in the Field Calculator (QGIS 2.18.5).

Creating a new function from Function Editor > New file, I'm able to start using a default function called func:

"""
Define new functions using @qgsfunction. feature and parent must always be the
last args. Use args=-1 to pass a list of values as arguments
"""

from qgis.core import *
from qgis.gui import *

@qgsfunction(args='auto', group='Custom')
def func(value1, feature, parent):
    return value1

At the beginning of the above code, I noticed this:

Use args=-1 to pass a list of values as arguments

Desiring to pass, for example, this list:

my_list = ['a', 'b', 'c']

as an input parameter, I tried to use args=-1 instead of args='auto':

@qgsfunction(args=-1, group='Custom')
def my_func(my_list, feature, parent):
    return my_list

but I wasn't able to add this list for my custom function because I wrote it using an invalid syntax:

enter image description here

What am I doing wrong? Or maybe I made some confusion about the using of args?

2 Answers 2

5

After some trial-and-errors, I found a working solution.

For passing a list as an argument, it would be enough setting the length of the list as a value for the args parameter. Then, since a list can't be returned by the function, it is necessary to specify a value from the list.

In my case, I need to rewrite the function in this way:

@qgsfunction(args=3, group='Custom')
def my_func(my_list, feature, parent):
    val = my_list[1]
    return val

and call the function by directly inserting only a list as a parameter:

enter image description here

As desired, the function returns the second value from the list which is directly specified inside the parentheses (without recurring to the square brackets as it is usually done for lists).

2
  • i think the expression editor uses its own parser, I don't think it supports things like python lists and dicts in expressions (you can use them inside your python function, but might need to return them as strings for example).
    – Steven Kay
    Mar 30, 2017 at 23:01
  • @StevenKay do you think that my approach is wrong? Thinking about my solution, it will probably also work if I leave args='auto' (I didn't test it). For the return value, instead, I don't know if it is possible to return a list.
    – mgri
    Mar 30, 2017 at 23:11
4

Would be interesting to see examples on how to use args=-1 as I also couldn't find much information about it. But when you do use it, it seems as if it automatically treats the input argument as a list without you having to make it.

For example, if we use:

from qgis.core import *
from qgis.gui import *

@qgsfunction(args=-1, group='Custom')
def my_func(my_list, feature, parent):
    val = my_list[1]
    return val

And use an expression like:

my_func('a','b','c', 'd', 'e', 'f', 'g')

It returns 'b':

Result

As val is returning the second item of my_list, it does seem that my_func('a','b','c', 'd', 'e', 'f', 'g') is instead being read like my_func(['a','b','c', 'd', 'e', 'f', 'g']).


You can also see this by returning the input argument as a string using:

from qgis.core import *
from qgis.gui import *

@qgsfunction(args=-1, group='Custom')
def my_func(my_list, feature, parent):
    return str(my_list)

And using the same expression:

my_func('a','b','c', 'd', 'e', 'f', 'g')

Second result

We can see the input argument (which seemed to have been a list) being converted to a string.



Hopefully a QGIS dev can enlighten us :)

3
  • 1
    You are right, it seems that the usual Python syntax doesn't work for passing a list in a custom function. I didn't edit my answer after the further attempts, but you confirmed what I discovered today, i.e. that it isn't necessary typing the maximum number of input parameters for args but it would be enough setting a -1 value. This operation exactly corresponds to the quote I enlightened in my original question. So, in my opinion, you answer is the best answer!
    – mgri
    Mar 31, 2017 at 10:43
  • @mgri - I'm glad it was helpful but whether or not it is correct...I'm hoping a QGIS dev could post an answer and confirm what the behavour is =)
    – Joseph
    Mar 31, 2017 at 10:50
  • 1
    It should be like that: args='auto' for passing any number of parameters; args=n for passing n parameters; args=-1 for passing a list of parameters.
    – mgri
    Mar 31, 2017 at 11:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.