da bin ich wieder. Ich habe mir ursprünglich bei stackoverflow How can I store multiple function as a value of the dictionary? Hilfe geholt. Es geht darum mehrere Funktionen in einem Wörterbuch zu speichern. Die Antwort ist sehr hilfreich, allerdings bin ich dabei, diesen verdichteten Quelltext aufzudröseln und zu kapieren. Dabei bin ich insebesondere bei Zeile 32 stecken geblieben. Die Frage habe in auf Englisch im Kommentar direkt dort hingeschrieben. Ich frage mich, wieso der f-Funktion zwei Argumenteparameter übergeben werden, die im Grunde leer sind? Wenn ich *args und **kwargs lösche, werden meine beiden Argumente (test_1 und test_2) trotzdem mitgeliefert und an die jeweiligen test-Funktionen übergeben.
Und wenn wir schon dabei sind. In der chain_funcs-Funktion ist ja eine weitere Funktion (call_funcs). Aber wieso führt chain_funcs die weitere Funktion nicht aus, sobald chain_funcs aufgerufen wird? Ich dachte immer, sobald eine Funktion aufgerufen wird, wird alles innerhalb des Korpus der Funktion ausgeführt. Alles was in der Funktion ist wird ausgeführt. Durch die print-Anweisungen sehe ich aber, dass chain_funcs ab Zeile 16 direkt zum return springt, dann die call_funcs()-Funktion zurückliefert. Und da in Zeile 53 die zurückgelieferte Funktion mittels der runden Klammern aufgerufen wird, so wird die call_funcs()-Funktion aufgerufen. Aber die chain_funcs()-Funktion selbst ruft beim Aufruf die call_funcs()-Funktion nicht auf.
Code: Alles auswählen
from functools import partial
def chain_funcs(*funcs):
"""This closure returns a callable to call multiple functions"""
# *args is used to send a non-keyworded variable
# length argument list to the function.
print "STEP 01: chain_funcs is called"
print "STEP 02: given *funcs", funcs # (<functools.partial object at 0x02DEA600>,
# <functools.partial object at 0x02DEA690>)
print "STEP 03: given *funcs type", type(funcs) # <type 'tuple'>
# chain_funcs skips this block and returns call_funcs
def call_funcs(*args, **kwargs):
""" Here a nested function is created. """
# *args is used to send a non-keyworded variable
# length argument list to the function and **kwargs
# allows you to pass keyworded variable length of arguments
# to a function
print "STEP 04: call_funcs is called"
print "STEP 05: given *args content", args # output: ()
print "STEP 06: given *args type", type(args) # output: <type 'tuple'>
print "STEP 07: given **kwargs content", kwargs # output: {}
print "STEP 08: given *kwargs type", type(kwargs) # output: <type 'dict'>
for f in funcs:
print "STEP 09: f", f # output: <functools.partial object at 0x0190A600>
print "STEP 10: f type", f # output: <functools.partial object at 0x0190A600>
f(*args, **kwargs) # <-- We know that *args and **kwargs are empty,
# but why are you giving these empty arguments?
# When I remove these arguments (*args and **kwargs),
# the given arguments 'test_1' and 'test_2' are still passed
# and printed.
print "STEP 11: return call funcs", call_funcs
print "STEP 12: return call funcs type", type(call_funcs)
return call_funcs
def test_1(arg_1 = None):
print "printing from test_1 func with text: {}".format(arg_1)
def test_2(arg_2 = None):
print "printing from test_2 func with text: {}".format(arg_2)
# Here we store multiple functions in a dictionary
dic = {'a': chain_funcs(partial(test_1, arg_1='test_1'),
partial(test_2, arg_2='test_2'))}
dic['a']() # First I use the the key to obtain its value.
# When attempting to access the 'value' the chain_funcs-function is called.
# The called function returns a callable-object.
# An now the returned callable will be called - with round brackets.