Seite 1 von 1

Funktionen mit for-loop bauen

Verfasst: Dienstag 15. Februar 2011, 16:32
von byrd_cleveland
Hallo Forum,

ich wollte gerne Funktionen bauen, etwa so:

Code: Alles auswählen

liste1 = []

for zahl in (1,2,3,4):
    def funktion():
        print(zahl)

    liste1.append(funktion)

random.choice(liste1)()
dabei spuckt er natürlich immer vier aus. Mich interessiert, ob man von der Arbeitsweise her es überhaupt so macht (Funktionen bauen lassen) und wenn ja, wie man dann erreichen kann, dass er dann die entsprechende Zahl und nicht immer vier ausgibt.
(ich verwende python 3.1.3)

gruß

Re: Funktionen mit for-loop bauen

Verfasst: Dienstag 15. Februar 2011, 16:47
von Hyperion
Dazu solltest Du Dir mal Dekoratoren angucken! Die Frage geht ja in den Bereich der Metaprogrammierung und daher ja, so was macht man schon. Dieses Beispiel finde ich zwar wenig sinnvoll, aber generell wird so etwas duchaus gemacht. Iirc gab es da einen recht guten Blogeintrag bei IBM.

Man sieht so was beispielsweise viel bei Rahmenwerken fürs Web, wo man mit Hilfe von Dekoratoren Funktionen an einen Endpunkt oder auch ein Template bindet.

Re: Funktionen mit for-loop bauen

Verfasst: Dienstag 15. Februar 2011, 16:50
von derdon
Bei dem einfachen Beispiel geht es so:

Code: Alles auswählen

>>> from __future__ import print_function
>>> f = print
>>> import random
>>> f(random.choice(xrange(1, 5)))
1
>>> f(random.choice(xrange(1, 5)))
2
>>> f(random.choice(xrange(1, 5)))
4
>>> f(random.choice(xrange(1, 5)))
3
>>> f(random.choice(xrange(1, 5)))
2
Wobei da die Zuweisung ``f = print`` natürlich sinnfrei erscheint. f könnte aber auch anders definiert sein; muss ja nur eine Funktion sein, die einen Parameter erwartet.

Re: Funktionen mit for-loop bauen

Verfasst: Dienstag 15. Februar 2011, 16:57
von Hyperion
Ich dachte er meint so was:

Code: Alles auswählen

In [17]: def decorate(value):
   ....:     def foo():
   ....:         print(value)
   ....:     return foo
   ....:

In [18]: funcs = map(decorate, range(5))

In [19]: funcs
Out[19]:
[<function foo at 0x010D3DF0>,
 <function foo at 0x010D3CF0>,
 <function foo at 0x010D3C30>,
 <function foo at 0x010D3F30>,
 <function foo at 0x010DC030>]

In [20]: choice(funcs)()
4

In [21]: choice(funcs)()
0

Re: Funktionen mit for-loop bauen

Verfasst: Dienstag 15. Februar 2011, 16:59
von EyDu
Oder alternativ:

Code: Alles auswählen

>>> funcs = []
>>> for zahl in range(4):
...     def func(zahl=zahl):
...         print zahl
...     funcs.append(func)
... 
>>> funcs[0]()
0
>>> funcs[1]()
1
oder:

Code: Alles auswählen

>>> import functools
>>> funcs = []
>>> for zahl in range(4):
...     def func(zahl):
...         print zahl
...     funcs.append(functools.partial(func, zahl))
...                                                                                                                  
>>> funcs[0]()                                                                                                       
0                                                                                                                    
>>> funcs[1]()                                                                                                      
1

Re: Funktionen mit for-loop bauen

Verfasst: Dienstag 15. Februar 2011, 17:10
von byrd_cleveland
die letzten beiden Beiträge sind das was ich brauche - vielen dank

Re: Funktionen mit for-loop bauen

Verfasst: Dienstag 15. Februar 2011, 18:00
von BlackJack
@Hyperion: Ich weiss nicht ob `decorate()` so ein passender Name ist, denn es ist ja im Python-Sinn eigentlich kein "decorator". Ich hätte es vielleicht `make_foo()` oder so genannt.

@EyDu: Im zweiten Beispiel hätte man ``def func`` aus der Schleife herausziehen können. So werden da drei im Grunde sinnlose Funktionsobjekte in der Schleife erzeugt. :-)

Re: Funktionen mit for-loop bauen

Verfasst: Dienstag 15. Februar 2011, 18:15
von EyDu
Vielleicht mag ich überflüssige Objekte :wink:

Re: Funktionen mit for-loop bauen

Verfasst: Dienstag 15. Februar 2011, 18:38
von Leonidas
Ich frage mich eher was der OP eigentlich machen will. Denn das was er da gepostet hat, wirkt nicht wie ein irgendwie nützlicher Code.