Reputation: 343
I wrote this in python 3 and am curious why the generator, produced under the @staticmethod
decorator by the yield
statement points to the same generator object per instance, yet produces instance specific results?
class Note:
def __init__(self):
pass
@staticmethod
def gen():
x = 0
while True:
x +=1
yield x
def id(self):
print(self.gen)
a = self.gen
print(next(a()))
n1 = Note()
n2 = Note()
print(n2.id(),n1.id())
This outputs:
<function Note.gen at 0x6ffffd7dd08>
1
<function Note.gen at 0x6ffffd7dd08>
1
None None
Upvotes: 1
Views: 1037
Reputation: 19372
No, it does not. Try with one instance, the same will happen:
n1 = Note()
print(n1.id(), n1.id())
It creates one generator per call to id()
, i.e. per call to gen()
.
EDIT (explanation of generators)
I'll try to explain with this example:
>>> def gen():
... yield 1
... yield 2
... yield 3
... yield 4
...
>>>
>>> gen
<function gen at 0x00000000029119C8>
>>> gen
<function gen at 0x00000000029119C8>
>>> g1 = gen()
>>> g2 = gen()
>>> g1
<generator object gen at 0x00000000025515A0>
>>> g2
<generator object gen at 0x000000000258B870>
>>> next(g1)
1
>>> next(g1)
2
>>> next(g2)
1
>>> next(g2)
2
>>> next(g1)
3
>>>
As you can see above, gen
is not a generator. It is a function. The return value of that function is a generator. So, when I printed gen
multiple times, I got the same function. However, when I called it twice, I got two generators g1
and g2
. Each of them holds its state, as you can see in calls to next
.
EDIT 2 (original example fixed)
BTW, I guess in your code you were trying to do this:
import itertools
class Note:
gen = itertools.count(1)
def __init__(self):
self.id = next(self.gen)
n1 = Note()
n2 = Note()
print(n2.id, n1.id)
EDIT 3 (objects in the same address)
Try this example:
class A:
def __init__(self, name):
self.name = name
print('Created a new A %s with name %s' % (self, name))
def f(name):
# create a new object A
a = A(name)
# a not stored anywhere, so Python will delete it now
f('one')
f('two')
f('three')
In my test, it outputs:
Created a new A <__main__.A object at 0x00000000029C0CF8> with name one
Created a new A <__main__.A object at 0x00000000029C0CF8> with name two
Created a new A <__main__.A object at 0x00000000029C0CF8> with name three
Upvotes: 1
Reputation: 1124000
You created two generators; each call to Note.gen()
produces a new generator object. The same would happen if you made these functions outside the class.
Upvotes: 0