Gå til innhold

Anbefalte innlegg

i sammenheng med tråden "GTK: "Next" knapp - endre label etter trykk" ( https://www.diskusjon.no/index.php?showtopi...dpost&p=5092609 ) tenkte jeg at en closure måtte være en fin løsning ..

 

..men så stusser jeg på hvordan man får til dette i Python på enklest mulig måte.. (fannt noen artikler om det via google, men det er mulig jeg må gi meg og finne frem en bok ang. hvordan data blir bundet til navn i Python)

 

her er opplegget i Lisp:

;; Returns a function. The function takes no 
;; parameters and returns a number that is increased
;; by one at each call to it.
(defun myClosure ()
 (let ((number 0))
   (lambda ()
     (incf number))))


(let ((closure1 (myClosure))
      (closure2 (myClosure)))
 (format t "~A~%" (funcall closure1))
 (format t "~A~%" (funcall closure1))
 (format t "~A~%" (funcall closure1))
 (format t "~A~%" (funcall closure2))
 (format t "~A~%" (funcall closure2))
 (format t "~A~%" (funcall closure1))
 (format t "~A~%" (funcall closure1)))


#|
1
2
3
1
2
4
5
|#

 

( http://paste.lisp.org/display/13130 )

 

edit:

altså, funksjonen itererte over et sett meldinger til bruk i gtk-labelen da, i stedet for disse tallene som øker ..... :)

Endret av dayslepr
Lenke til kommentar
Videoannonse
Annonse

Etter å ha lest fort igjennom den andre tråden din vil jeg si at noen enkle 'if' tester er en grei løsning. Om du absolutt må ha det "avansert" kan du kanskje bruke en generator.

 

def next_label():
  yield "hei";
  yield "hello";
  yield "osv";
  return "siste verdi";

 

Så kan du si (i button click hendelsen):

label.set_text(next_label());

 

Lisp eksempelet ditt kan også lages som en generator i Python:

def MyClosure():
   i = 0
   while True:
      yield i
      i = i + 1

 

hver gang du kaller MyClosure() vil du få det neste tallet.

Her er det imidlertid greit å forstå at dette er en matematisk funksjon som er enkel å modellere. Det er ingen måte å regne seg fra "hei" til "hello" og derfor fungerer ikke noe lignende med den typen strenger (om du ikke har hardkodet alt som i eksempelet øverst).

Lenke til kommentar

hm -- jeg må nesten se litt på dette med generatorer i Python ..nytt konsept for meg, og fikk det ikke helt til å fungere .. det får bli i morra, har heldigvis fri da; er trøtt som ei strømpe nå .. :)

 

ang. det på slutten så var det noe slikt jeg tenkte meg det:

 

(let ((label (list "first" "second" "third")))
 (defun myClosure ()
   (let ((pos -1))
     (lambda ()
       (nth (setf pos (mod (+ pos 1) 
                           3))
            label)))))
   

#|
cl-user> (let ((closure1 (myClosure))
               (closure2 (myClosure)))
          (format t "closure1: ~A~%" (funcall closure1))
          (format t "closure1: ~A~%" (funcall closure1))
          (format t "closure2: ~A~%" (funcall closure2))
          (format t "closure2: ~A~%" (funcall closure2))
          (format t "closure1: ~A~%" (funcall closure1))
          (format t "closure1: ~A~%" (funcall closure1))
          (format t "closure1: ~A~%" (funcall closure1))
          (format t "closure2: ~A~%" (funcall closure2))
          (format t "closure2: ~A~%" (funcall closure2)))
          

closure1: first
closure1: second
closure2: first
closure2: second
closure1: third
closure1: first
closure1: second
closure2: third
closure2: first
nil
|#

 

 

edit:

eller veldig enkelt da, om det kun er snakk om en label (en "instans" egentlig):

(let ((label (list "first" "second" "third"))
      (pos -1))
 (defun myClosure ()
   (nth (setf pos (mod (+ pos 1) 
                       3))
        label)))


#|
cl-user> (myClosure)
"first"
cl-user> (myClosure)
"second"
cl-user> (myClosure)
"third"
cl-user> (myClosure)
"first"
cl-user> (myClosure)
"second"
cl-user> (myClosure)
"third"
cl-user> (myClosure)
"first"
cl-user> (myClosure)
"second"

Endret av dayslepr
Lenke til kommentar

def gen():
  while True:
       yield "first";
       yield "second";
       yield "third";

 

da :)

 

Eller med liste som i lispen:

def gen():
  l = ("first", "second", "third")
  i = 0
  while True:
       yield l[i % len(l)]
       i += 1

 

Siden den første er enklest å lese er det best å bruke den.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...