2016-01-10 3 views
0

Я пытаюсь выяснить, почему я получаю generator вместо того, чтобы получать товар, напечатанный со второго раза, я определяю Scrape(). Я не запрашивал результат yield, который мне кажется странным, что он возвращает один.Python уступает, если не запрашивается методом объекта

Я хотел бы избежать этого, предположив, что это возможно и хотелось бы знать, почему это происходит. См. Комментарий в коде, если вам трудно понять или прокомментировать последние for loop

Это рабочий код, который можно протестировать на python 2.7 без изменений. В коде симуляция моей фактической проблемы, о которой я не знал, я мог бы воссоздать с более простым примером по сравнению с исходным кодом.

from Tkinter import * 
import ttk 
import threading 

class Gui(ttk.Frame): 
    def __init__(self, master): 
     ttk.Frame.__init__(self, master) 
     self.master = master 

     self.var = BooleanVar() 
     self.numbers = IntVar() 

     self.var.set(False) 
     varbox = ttk.Checkbutton(self.master, text="On/OFF", variable=self.var, onvalue=True) 
     varbox.pack() 

     btn = Button(self.master, text="Start", command=self.start_scan) 
     btn.pack() 
     entry = Entry(self.master, textvariable=self.numbers) # normally user would enter a number for now we assume 100 
     entry.pack() 
     self.numbers.set(25) 


    def start_scan(self): 
     # start scan with a thread 
     true_here = self.var.get() # let us say this is True value 
     numbers = self.numbers.get() 
     t = ThreadIt(true_here, numbers) # gave thread True, 100 
     t.start() 


class Scrape(object): 
    def __init__(self, numbers): 
     self.numbers = numbers 
     if self.numbers < 5: 
      self.numbers = 20 

    def do_stuff(self, var=False): 

     # do things to change the world 
     for i in range(2, self.numbers): # -> 99 
      if var: 
       yield i * 20 # increase the number to we can recall this function 
      else: 
       print i 

class ThreadIt(threading.Thread): 
    def __init__(self, var, numbers): 
     super(ThreadIt, self).__init__() 
     self.var = var 
     self.numbers = numbers 

    def run(self): 
     foo = Scrape(self.numbers) 
     result = foo.do_stuff(var=self.var) # since numbers is 25 this would yield from 2 to 24 as var is sent to TRUE 

     if result: # if var above is false below wouldn't have happen 
      for i in result: 
       yielded = Scrape(i) 
       print yielded , "foo" # prints something line: <__main__.Scrape object at 0x112da4d90> 

       res = yielded.do_stuff(var=False) 

       print res # suppose no be None because its not suppose to yield since var is False but it prints generator as below 
       # <generator object do_stuff at 0x10eef1aa0> 
       for i in res: # this is not suppose to be a generator (Generator was done in result) 
        print i 
       print "Finished" 




root = Tk() 
app = Gui(root) 
root.mainloop() 
root.destroy() 
+4

Вызов генератора возвращает объект генератора., Он не выполняет его! Это дает только то, что вы вызываете 'next()' или 'send()' на объекте генератора, прямо или косвенно, как в цикле 'for'. – cdarke

ответ

1

Я думаю, вы бы извлечь большую пользу от чтения this answer

Для вашего конкретного случая, yielded = Scrape(i) действительно создает объект типа Scrape. И yielded.do_stuff(var=False) возвращает генератор, потому что оператор yield используется в его определении. Так как var - False, он не будет генерировать какой-либо элемент, хотя и будет просто выполнять линию print i до исчерпания цикла for.

Но да, требуется время, чтобы прочитать первую ссылку, которую я дал, это красиво

Смежные вопросы