Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
79 views
in Technique[技术] by (71.8m points)

Python variable number of parameters in callback

I am trying to implement a callback system in Python that is similar to how JavaScript can have different numbers of parameters in its callbacks. Ideally, I want to achieve this without using *args or **kwargs in the parameters of my callbacks.

My Goal

What I want is something that looks roughly like this:

def callback1(val):
    print(val)

def callback2(x, y):
    print(x, y)

def callback3(a, b, c):
    print(a, b, c)

def foo(callback):
    callback(1, 2, 3) # Always has 3 arguments to pass

foo(callback1)  # Fails. Should print "1"
foo(callback2)  # Fails. Should print "1 2"
foo(callback3)  # Ok. Prints "1 2 3"

Perhaps a more verbose way of putting it would be:

# num_params() method isn't real (that I know of), but this is an
# inelegant example of how the callbacks might work if it were
def foo2(callback):
    if num_params(callback) == 1:
        callback(1)
    elif num_params(callback) == 2:
        callback(1, 2)
    elif num_params(callback) == 3:
        callback(1, 2, 3)

What I Don't Want

I don't want to use *args or **kwargs in each callback (unless this isn't possible any other way) like the following:

# This is just SO ugly
def callback1(*args):
    print(args[0])

def callback2(*args):
    print(args[0], args[1])

def callback3(*args):
    print(args[0], args[1], args[2])

JavaScript Equivalent

This is relatively common in JavaScript. For example, one can supply the callback of a .forEach() function with 1, 2, or 3 arguments:

let myArray = [1, 2, 3, 4]

// Valid
myArray.forEach((element) => {
   // Do stuff with the element only
});

// Valid
myArray.forEach((element, index) => {
   // Do stuff with the element AND the index
});

// Valid
myArray.forEach((element, index, array) => {
   // Do stuff with the element, index and the whole array
});

However, despite my best efforts in Google searching, I have no idea how to implement this in Python (or even in JavaScript for that matter, but that's beside the point; I hope this doesn't come back to bite me).

I would very much like to know if this is possible in Python and/or what the proper term is for this coding technique.

question from:https://stackoverflow.com/questions/65662021/python-variable-number-of-parameters-in-callback

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

What's wrong with args and kwargs? It is the pythonic way to do that. Python is not JavaScript. If you do not like accessing args by indexes like args[0], args[1], etc, you could just define some args like usual, and rest (unused args) - in *args:

def callback1(a, *args):
    print(a)

def callback2(a, b, *args):
    print(a, b)

def callback3(a, b, c):
    print(a, b, c)

Also you can unpack them in the function:

def callback1(*args):
    a, *rest = args
    print(a)

It makes it more verbose inside, but same definition for all callbacks.

Also it's common to name variables, you are not going to use with _ (underscore) instead of args, rest, etc.:

def callback1(a, *_):
    print(a)

def callback1(*args):
    a, *_ = args
    print(a)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...