Hoe een eenvoudige callback-functie schrijven?

Python 2.7.10

Ik heb de volgende code geschreven om een ​​eenvoudige callback-functie te testen.

def callback(a, b):
    print('Sum = {0}'.format(a+b))
def main(callback=None):
    print('Add any two digits.')
    if callback != None:
        callback
main(callback(1, 2))

Ik ontvang dit wanneer ik het uitvoer:

Sum = 3
Add any two digits.

Waarom Add any two digitsis na Sum = 3? Ik denk dat het is omdat de callback-functie eerst wordt uitgevoerd. Hoe de callback-functie uit te voeren na alle andere code in main()Uitgevoerd?


Antwoord 1, Autoriteit 100%

In deze code

if callback != None:
    callback

CallBackOODIGE DOE NIETS; Het accepteert parameters – def callback(a, b):

Het feit dat u deed callback(1, 2)zal eerst die functie bellen, daardoor afdrukken Sum = 3.

Sinds CallBackRetourneert geen expliciete waarde, wordt teruggestuurd als None.

Dus, uw code is gelijk aan

callback(1, 2)
main()

Oplossing

Je zou kunnen proberen de functie in eerste instantie niet te bellen en gewoon zijn handvat te passeren.

def callback(sum):
    print("Sum = {}".format(sum))
def main(a, b, _callback = None):
    print("adding {} + {}".format(a, b))
    if _callback:
        _callback(a+b)
main(1, 2, callback)

Antwoord 2, Autoriteit 15%

Hier is wat u wilde doen:

def callback(a, b):
    print('Sum = {0}'.format(a+b))
def main(a,b,f=None):
    print('Add any two digits.')
    if f != None:
        f(a,b)
main(1, 2, callback)

Antwoord 3, Autoriteit 6%

Zoals vermeld in de opmerkingen, wordt uw callback geroepen wanneer deze wordt achtervolgd met open en nauwe parens; Zo wordt het gebeld wanneer je het passeert.

Misschien wilt u een lambda gebruiken en de waarden doorgeven.

#!/usr/bin/env python3
def main(callback=None, x=None, y=None):
    print('Add any two digits.')
    if callback != None and x != None and y != None:
        print("Result of callback is {0}".format(callback(x,y)))
    else:
        print("Missing values...")
if __name__ == "__main__":
    main(lambda x, y: x+y, 1, 2)

Antwoord 4, Autoriteit 6%

Het probleem is dat u de callback evalueert voordat u het als een vulbaar viel. Een flexibele manier om het probleem op te lossen zou dit zijn:

def callback1(a, b):
    print('Sum = {0}'.format(a+b))
def callback2(a):
    print('Square = {0}'.format(a**2))
def callback3():
    print('Hello, world!')
def main(callback=None, cargs=()):
    print('Calling callback.')
    if callback != None:
        callback(*cargs)
main(callback1, cargs=(1, 2))
main(callback2, cargs=(2,))
main(callback3)

Optioneel wilt u mogelijk een manier opnemen om zoekwoordargumenten te ondersteunen.


Antwoord 5, Autoriteit 4%

Uw code wordt als volgt uitgevoerd:

main(callback(1, 2))

CallBack-functie wordt aangeroepen met (1, 2)en retourneert None(zonder return-statement drukt uw functie Sum = 3en retourneert None)

mainfunctie wordt aangeroepen met Noneals argument (Dus callback != Nonezal altijd Falsezijn)


Antwoord 6

Dit is een oud bericht, maar misschien kan het volgende extra uitleg geven over het schrijven en gebruiken van een callback-functie, vooral als je je afvraagt waar het zijn argumenten vandaan haalt en of je toegang hebt tot de retourwaarden (als er geen manier is om haal het van de functie die de callback-functie nodig heeft).

De volgende code definieert een klasse CallBackdie twee callback-methoden (functies) heeft: my_callback_sumen my_callback_multiply. De callback-methoden worden ingevoerd in de methode foo.

# understanding callback
class CallBack:
    @classmethod
    def my_callback_sum(cls, c_value1, c_value2):
        value = c_value1 + c_value2
        print(f'in my_callback_sum --> {c_value1} + {c_value2} = {value}')
        cls.operator = '+'
        return cls.operator, value
    @classmethod
    def my_callback_multiply(cls, c_value1, c_value2):
        value = c_value1 * c_value2
        print(f'in my_callback_multiply --> {c_value1} * {c_value2} = {value}')
        cls.operator = '*'
        return cls.operator, value
    @staticmethod
    def foo(foo_value, callback):
        _, value = callback(10, foo_value)
        # note foo only returns the value not the operator from callback!
        return value
if __name__ == '__main__':
    cb = CallBack()
    value = cb.foo(20, cb.my_callback_sum)
    print(f'in main --> {value} and the operator is {cb.operator}')
    value = cb.foo(20, cb.my_callback_multiply)
    print(f'in main --> {value} and the operator is {cb.operator}')

resultaat:

in my_callback_sum --> 10 + 20 = 30
in main --> 30 and the operator is +
in my_callback_multiply --> 10 * 20 = 200 
in main --> 200 and the operator is *

Zoals je een waarde kunt zien voor de callback-functie c_value2, wordt deze verkregen van argument foo_valuein fooen gegeven in mainde waarde 20, terwijl c_value1het intern van fookrijgt, in dit geval de waarde 10 (en mogelijk niet duidelijk zichtbaar als foois een methode van een geïmporteerde module van een derde partij, zoals pyaudio).

De retourwaarde van de callback-functiefuncties kan worden opgehaald door deze toe te voegen aan de naamruimte van de klasse CallBack, in dit geval cls.operator

Other episodes