[Python-ideas] Generator/Coroutiine Ontology (was async/await in Python)
ncoghlan at gmail.com
Sat Apr 25 06:02:24 CEST 2015
On 18 April 2015 at 16:05, Andrew Barnert
<abarnert at yahoo.com.dmarc.invalid> wrote:
> On Apr 17, 2015, at 21:48, Rustom Mody <rustompmody at gmail.com> wrote:
>> On Sat, Apr 18, 2015 at 12:28 AM, Yury Selivanov
>> <yselivanov.ml at gmail.com> wrote:
>>> Hello python-ideas,
>>> Here's my proposal to add async/await in Python.
>>> I believe that PEPs 380 and 3156 were a major breakthrough for Python 3,
>> I am also interested in this topic --- from the other side.
>> As a teacher of python it is my finding that the
>> terminology/documentation around generators is rather chaotic and
>> Basically given:
>> def foo():
>> yield 1
>> bar = foo()
>> what do we call foo and what do we call bar?
>> It is suggested that foo is "generator-function" and bar is "generator-object"
>> Unfortunately python does not aid this distinction; witness
>>>>> def foo():
>> ... yield 1
>>>>> bar = foo()
>> <class 'function'>
>> <class 'generator'>
> I assume you're ok with the type(bar); the type of a generator object is named "generator", just like the type of a bound method object is named "method" and the type of an integer object is named "int", and so on.
> So presumably you don't like the former. But what about it?
> The only thing I can imagine is the fact that, even though a generator function is conceptually a "subkind" of function, there is no generator function subtype of the function type?
> But so what? There's no closure function subtype, just functions whose closure is nonempty; there's no positive int subtype, just ints whose value is positive; etc. And likewise, there's no callable supertype that function and method (and other things) inherit.
> If there were some additional API that a generator function should provide that other functions don't (or some implementation reason that makes it worth subclassing for convenience, I suppose), that would be a good reason for needing a subtype. For example, generator a subtype of iterator, just as file is, because they both add new methods that don't make sense for the base iterator type.
> But just wanting repr(type(x)) to give you more information about x, that's not a good reason to add a subtype.
> So, it seems to me like both of these are returning something you should reasonably expect.
Catching up on email following PyCon travel, there's a reasonable
question here related to the repr() of "foo" itself:
>>> def foo():
... yield 1
<function foo at 0x7f7dad9f7bf8>
>>> import dis
Argument count: 0
Kw-only arguments: 0
Number of locals: 0
Stack size: 1
Flags: OPTIMIZED, NEWLOCALS, GENERATOR, NOFREE
Modifying the repr of a function based on whether or not the GENERATOR
flag was set on the code object would be quite doable. For example,
the above could be:
<function foo at 0x7f7dad9f7bf8 (generator)>
type(foo) would still be unchanged, we'd just be exposing some
additional info in the value repr().
While it's a less significant behavioural difference than being a
generator function, a non-empty closure could conceivably also be
reported in the repr():
<function foo at 0x7f7dad9f7bf8 (closure)>
<function foo at 0x7f7dad9f7bf8 (closure,generator)>
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
More information about the Python-ideas