Funktionen mit for-loop bauen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
byrd_cleveland
User
Beiträge: 8
Registriert: Donnerstag 28. Januar 2010, 19:45

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ß
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

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.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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
Das Leben ist wie ein Tennisball.
byrd_cleveland
User
Beiträge: 8
Registriert: Donnerstag 28. Januar 2010, 19:45

die letzten beiden Beiträge sind das was ich brauche - vielen dank
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. :-)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Vielleicht mag ich überflüssige Objekte :wink:
Das Leben ist wie ein Tennisball.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten