0

Trying to incorporate a generator object into my code but some how its not working correctly.

def get_data():
    data = some_api_call
    result = data.json()
    return result

result looks like like this, where each {} is on new line:

{u'bytes_out': 1052.0, u'host': u'abc.com'}
{u'bytes_out': 52.0, u'host': u'def.com'}
{u'bytes_out': 5558.0, u'host': u'xya.com'}
...


def write_to_file(line):
    #replacing the write statement with a print for testing
    print(line)

def read_report(data):
    for line in data:
        yield line

def main():
    alldata = get_data()
    write_to_file(read_report(alldata))

My expectation here is that it should print out:

{u'bytes_out': 1052.0, u'host': u'abc.com'}
{u'bytes_out': 52.0, u'host': u'def.com'}
{u'bytes_out': 5558.0, u'host': u'xya.com'}

but what im getting back is :

<generator object read_report at 0x7fca02462a00>

not sure what I'm missing here

*** EDIT - fixed I was using it incorrectly

def main():
    all_data = get_data()
    for line in read_report(all_data)
        print(line)
Mohammad Jafari
  • 1,742
  • 13
  • 17
chowpay
  • 1,515
  • 6
  • 22
  • 44
  • `read_report` returns a generator. Why are you surprised? – DYZ Aug 20 '20 at 22:20
  • While `print` will call `str` on its argument for you, `generator.__str__` doesn't build a string by iterating over the instance; it returns a generic representation without any iteration. – chepner Aug 20 '20 at 22:20
  • @DYZ because I incorrectly thought that it would print out 1 line of the generator object what do I need to do to get the desired outcome? – chowpay Aug 20 '20 at 22:23
  • An iterator is something you can for loop over. This generator is essentially an iterator. – Mateen Ulhaq Aug 20 '20 at 23:04

1 Answers1

1

You can also print directly from a generator:

gen = range(1,10)
print(*gen, flush=True)
#out: 1 2 3 4 5 6 7 8 9

so for your case:

print(*read_report(all_data), flush=True)
Andreas
  • 8,694
  • 3
  • 14
  • 38
  • neat, whats the flush do? – chowpay Aug 20 '20 at 23:33
  • 1
    Essentially it forces a print from the buffer. You can read more here: https://stackoverflow.com/questions/15608229/what-does-prints-flush-do In your case it might not even be necessary, try it without the flush. – Andreas Aug 20 '20 at 23:40
  • This defeats the purpose of using a generator, as you have to generate the entire sequence in memory before `print` can being. – chepner Aug 21 '20 at 12:47
  • @chepner that is True, but in his example he uses it for printing only anyway. – Andreas Aug 21 '20 at 12:51
  • 1
    So? You can print the output line-by-line without reading every line into memory first. – chepner Aug 21 '20 at 12:55