On Thu, Jan 23, 2014 at 7:43 PM, Steven D'Aprano <st...@pearwood.info> wrote: > Generators are a kind of function, which are special. You can't inherit > from them:
I clarified my sloppy language in a reply. `__iter__` should be a generator function, not a generator. A generator function uses `yield` and `yield from` expressions, and returns a `generator` when called. In CPython, the code for a generator function is flagged as CO_GENERATOR: def genfun(): yield 1 flags = genfun.__code__.co_flags >>> inspect.CO_GENERATOR 32 >>> flags & inspect.CO_GENERATOR 32 But that's CPython specific; use the inspect API instead (2.6+): >>> inspect.isgeneratorfunction(genfun) True A "generator expression" also creates a generator. In CPython, this is implemented by calling an anonymous generator function that gets instantiated and called automagically. When a function is called, the interpreter creates a frame to evaluate the function's bytecode, given the function's globals and the current thread state. It combines the call's positional and keyword arguments with the `__defaults__` tuple and `__kwdefaults__` dict to set the parameters as local variables in the frame. For a closure, it also loads the free-variable `cell` objects from the `__closure__` tuple. Everything is ready to call PyEval_EvalFrameEx to evaluate the frame... Except if the code is flagged as CO_GENERATOR that doesn't happen. Instead the interpreter creates and returns a `generator` that references the frame as its `gi_frame` attribute. Calling the generator's `__next__` method in turn evaluates the frame up to a `yield` or `yield from` expression. `StopIteration` is raised when the frame executes a `return` statement or explicit `return None` -- or implicitly returns from the last line of the function. Like the function type, the generator type is finalized (i.e. doesn't allow subclassing). It's clear why that would be the case for the type of a singleton object such as None, Ellipsis, NotImplemented, and True/False (bool). In other cases, supporting subclassing would be more work (initial coding, bugs, maintenance -- who's volunteering?) for little gain. For example: slice and range. Other types are so closely linked to the language that I don't see why anyone would care to subclass them, such as function, method, generator, frame, code, and cell [1]. There's a fuzzy line there; property, classmethod, and staticmethod aren't finalized. [1] Listing every finalized type in CPython would be tedious. Here's a few more, if anyone cares: builtin_function_or_method, method_descriptor, classmethod_descriptor, member_descriptor, getset_descriptor, wrapper_descriptor, and method-wrapper. _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor