detecting a generstor passed to a funtion - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: detecting a generstor passed to a funtion (/thread-34953.html) |
detecting a generstor passed to a funtion - Skaperen - Sep-19-2021 what is the appropriate pythonic way for a function to detect that a generator is passed to it? i can do this: if type(arg).__name__=='generator': print('got a generator') else: print('did not get a generator')i cannot do: if isinstance(arg,generator): print('got a generator') else: print('did not get a generator')because generator is not defined.
RE: detecting a generstor passed to a funtion - buran - Sep-19-2021 look at collections.abc RE: detecting a generstor passed to a funtion - DeaD_EyE - Sep-19-2021 from collections.abc import Generator from typing import Generator as TypingGenerator from inspect import isgeneratorfunction, isgenerator def foo(): """Function""" def bar(): """Generatorfunction""" yield print("foo", isgeneratorfunction(foo)) print("bar", isgeneratorfunction(bar)) print("foo()", isgenerator(foo())) print("bar()", isgenerator(bar())) # Generator could not detect a Generatorfunction # but a Generator print("bar()", isinstance(bar(), Generator)) print("bar()", isinstance(bar(), TypingGenerator))I'm not sure about typing.Generator. It detects a generator, but typing is used for type hints, which is used for IDEs and Code Linters. One question, many solutions... RE: detecting a generstor passed to a funtion - buran - Sep-19-2021 (Sep-19-2021, 06:06 AM)DeaD_EyE Wrote: # Generator could not detect a GeneratorfunctionNot sure what you mean with this comment. The output is note, blank lines between output pairs are mine.
RE: detecting a generstor passed to a funtion - bowlofred - Sep-19-2021 Maybe looking for something like this? >>> g = (x for x in range(20)) >>> g <generator object <genexpr> at 0x10d4a6820> >>> import types >>> isinstance(g, types.GeneratorType) True RE: detecting a generstor passed to a funtion - DeaD_EyE - Sep-19-2021 (Sep-19-2021, 07:55 AM)buran Wrote: Not sure what you mean with this comment. The output is from inspect import isgeneratorfunction def normal_function(): return None def generator_function(): yield print("Type of normal_function", type(normal_function)) print("Type of generator_function", type(generator_function)) print("How to find out if generator_function is a generator without calling it?") print("Return-Type of generator_function()", type(generator_function())) print("Now the detection of a generator_function without calling this function") print(isgeneratorfunction(generator_function)) A simplified implementation from inspect just for functions, not methods.(it could also detect generator methods, but the code in inspect is a bit different and does crazy wrapping) CO_GENERATOR = 32 def isgeneratorfunction(func): if hasattr(func, "__code__"): return bool(func.__code__.co_flags & CO_GENERATOR) return FalseWith typing.Generator and with collections.abc.Generator you can't detect if a function will return a generator without calling the function. You can call the generator and without iterating it or use of the send method, the generator does not execute the code inside. The thing is, that you call a function to check if it's a Generator and if it's the case, to throw it away or vice versa. But there is another important point to bring up. If you have a function which could be a generator, but you don't know it and another fact is, if you call the wrong function, it can take much time to compute something. But what if you have a worker with a bunch of functions/generators/coroutines and you need to branch to put the tasks into the right worker. The synchronous functions to the threaded/multiprocess-worker, the generators to an async worker aswell the coroutines. Calling a generatorfunction, return the generator. Calling a coroutine, returns the coroutine object. Calling a ordinary function, returns the result. But if you want to put this function with arguments to the threaded worker, you can't call the function inside the process which put the tasks to the right workers. So you need to be able to detect this, before you call a function. The function has in the code-object flags, which define which type the function is. The Flags: You should be careful what you ask. The rabbit hole is quite deep.
RE: detecting a generstor passed to a funtion - Skaperen - Sep-20-2021 (Sep-19-2021, 08:00 AM)bowlofred Wrote: Maybe looking for something like this? so, could i do: from types import GeneratorType as generatorfollowed by that 2nd failing example of mine? RE: detecting a generstor passed to a funtion - Skaperen - Sep-20-2021 (Sep-19-2021, 11:08 AM)DeaD_EyE Wrote: You should be careful what you ask. The rabbit hole is quite deep. i was asking about the kind of generator that can be expressed between the () in a call to a function, but i probably should also be detecting for a callable function that has a yield statement, as determined by the compiler? RE: detecting a generstor passed to a funtion - bowlofred - Sep-20-2021 (Sep-20-2021, 05:42 PM)Skaperen Wrote: so, could i do: Looks good to me.. from types import GeneratorType as generator arg = (x for x in range(5)) if isinstance(arg,generator): print('got a generator') else: print('did not get a generator')
RE: detecting a generstor passed to a funtion - Skaperen - Sep-23-2021 i am happy, now. thanks! |