473,669 Members | 2,457 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

creating generators from function

I use a coroutine/generator framework for simulating concurrent processes.

To do this, I write all my functions using the general form:

while True:
do stuff
yield None

To make these generator functions compatible with a standard thread
interface, I attempted to write a decorator which converts a standard
function into a generator function (code attached below).
Unfortunately, I received an exception, before I could test if my idea
would work:

TypeError: cannot create 'generator' instances

I guess I can go the other way, and convert a generator into a
function, but that just doesn't seem right.

Is there anyway solve the problem described?

Sw.
from opcode import opmap
import types
globals().updat e(opmap)

def generatorize(f) :
co = f.func_code
nc = [ord(x) for x in co.co_code]
for op,i in enumerate(nc):
if op == RETURN_VALUE:
nc[i] = YIELD_VALUE
newcode = ''.join([chr(x) for x in nc])
codeobj = type(co)(co.co_ argcount, co.co_nlocals, co.co_stacksize ,
co.co_flags, newcode, co.co_consts, co.co_names,
co.co_varnames, co.co_filename, co.co_name,
co.co_firstline no, co.co_lnotab, co.co_freevars,
co.co_cellvars)

print types.Generator Type(f)(codeobj , f.func_globals, f.func_name,
f.func_defaults , f.func_closure)
return f

@generatorize
def f():
while True:
return 1

def g():
while True:
yield 1

print g()
print f()
Jul 18 '05 #1
10 1968
Simon Wittber wrote:
I use a coroutine/generator framework for simulating concurrent processes.

To do this, I write all my functions using the general form:

while True:
do stuff
yield None

To make these generator functions compatible with a standard thread
interface, I attempted to write a decorator which converts a standard
function into a generator function (code attached below). [snip] @generatorize
def f():
while True:
return 1

def g():
while True:
yield 1

print g()
print f()


I'm a little confused as to what you're trying to do here. The f()
function, in particular, doesn't make much sense -- the 'while True'
doesn't do anything since the 'return 1' is executed on the first time
through the loop. If you really do want to turn your functions into
generators of the form:

while True:
do stuff
yield None

why can't you just do:
def generatorize(f) : .... def new_f(*args, **kwds):
.... while True:
.... f(*args, **kwds)
.... yield None
.... return new_f
.... @generatorize .... def f():
.... return 1
.... i = f()
print i.next() None print i.next()

None

Basically, I've assumed that 'do stuff' is the function that's being
wrapped.

Steve
Jul 18 '05 #2
Simon Wittber wrote:
I use a coroutine/generator framework for simulating concurrent processes.

To do this, I write all my functions using the general form:

while True:
do*stuff
yield*None

To make these generator functions compatible with a standard thread
interface, I attempted to write a decorator which converts a standard
function into a generator function (code attached below).
Unfortunately, I received an exception, before I could test if my idea
would work:

TypeError: cannot create 'generator' instances

I guess I can go the other way, and convert a generator into a
function, but that just doesn't seem right.

Is there anyway solve the problem described?


Generators are just functions with an extra flag set. I tried the following
modification of your code:

<code>
from opcode import opmap
globals().updat e(opmap)

def _f(): pass
function = type(_f)
del _f

def generatorize(f) :
co = f.func_code
nc = [ord(x) for x in co.co_code]
for i, op in enumerate(nc[:-1]):
if op == RETURN_VALUE:
nc[i] = YIELD_VALUE
newcode = ''.join([chr(x) for x in nc])

codeobj = type(co)(co.co_ argcount, co.co_nlocals, co.co_stacksize ,
co.co_flags + 32, newcode, co.co_consts,
co.co_names,
co.co_varnames, co.co_filename, co.co_name,
co.co_firstline no, co.co_lnotab, co.co_freevars,
co.co_cellvars)

return function(codeob j, f.func_globals, f.func_name,
f.func_defaults , f.func_closure)

@generatorize
def f():
while True:
return 1

def g():
while True:
yield 1

print g()
print f()

import itertools
print list(itertools. islice(f(), 5))
</code>

The hardest part was to find the enumerate() bug. I agree with Steven that
converting between functions and generators by replacing return with yield
and vice versa is hardly ever useful, though.

Peter




Jul 18 '05 #3
> I'm a little confused as to what you're trying to do here. The f()
function, in particular, doesn't make much sense


I see I am misunderstood. The example was contrived, and it seems, incorrect.

I simulate threads, using generator functions and a scheduler.

My implementation lives here: http://metaplay.com.au/svn/LGT/LGT/nanothreads.py

If the same functions were to run inside a normal thread, they would
need to loop forever, rather than yield None on each iteration. I see
now that replacing return with yield won't work, a yield instruction
needs to be inserted somewhere.

I guess this changes my question to: Can I convert a function
containing an infinite loop, into a generator which will yield on each
iteration?

Sw.
Jul 18 '05 #4
Simon Wittber wrote:
I guess this changes my question to: Can I convert a function
containing an infinite loop, into a generator which will yield on each
iteration?


Why don't you just use threads? It would probably be easier in the long run...

--
Timo Virkkala
Jul 18 '05 #5

"Simon Wittber" <si**********@g mail.com> wrote in message
news:4e******** *************** *@mail.gmail.co m...
I guess this changes my question to: Can I convert a function
containing an infinite loop, into a generator which will yield on each
iteration?


A function containing an infinite loop will never return, so it is bugged
and useless unless it does has an external effect with something like
'print xxx' within the loop. Even then, it depends on 'while True:'
actually meaning 'while <external stop signal (control-C, reset, power off)
not present>'. The obvious change for a buggy function is to insert a
yield statement. For the implicit conditional with print, change 'print'
to 'yield'.

Note 1. Many algorithm books, especially when using pseudocode, use 'print
sequence_item' to avoid language specific details of list construction.
One of the beauties of Python2.2+ is that one can replace simply 'print'
with 'yield' and have a working algorithm.

Note 2. Delving deep into CPython internals, as you are, is CPython hacking
rather than Python programming per se. Fun, maybe, but I wonder if this is
really to best way to do what you want to do.

Terry J. Reedy

Jul 18 '05 #6
> A function containing an infinite loop will never return, so it is bugged
and useless unless it does has an external effect with something like
'print xxx' within the loop.
I thought the idiom:

while True:
#code which iterates my simulation
if condition: break

wat quite normal. This is the style loop I am using.
Note 2. Delving deep into CPython internals, as you are, is CPython hacking
rather than Python programming per se. Fun, maybe, but I wonder if this is
really to best way to do what you want to do.


I am trying to allow two modes of concurrency, (threading, and
pseudo-threading using generators) without having to change my
application code. If either CPython or Python hacking can provide a
solution, I'm not sure, but I would be happy with either.

Sw.
Jul 18 '05 #7

"Simon Wittber" <si**********@g mail.com> wrote in message
news:4e******** *************** @mail.gmail.com ...
I thought the idiom:

while True:
#code which iterates my simulation
if condition: break

wat quite normal. This is the style loop I am using.
Yes, quite normal. This is Python's version of do...until, synthesized
from while and break. As most people use the term, this is *not*
structurally an infinite loop (meaning no break) and also not functionally
so unless the condition is such that it never breaks either for some or all
inputs to the function.
I am trying to allow two modes of concurrency, (threading, and
pseudo-threading using generators) without having to change my
application code. If either CPython or Python hacking can provide a
solution, I'm not sure, but I would be happy with either.


One Python level approach would be to quote the text of the function defs
that need to switch and then either programmaticall y edit them or not
before exec-ing them. Also messy, but more robust against version and
implementation changes.

Terry J. Reedy

Jul 18 '05 #8
Simon Wittber <si**********@g mail.com> writes:
A function containing an infinite loop will never return, so it is bugged
and useless unless it does has an external effect with something like
'print xxx' within the loop.


I thought the idiom:

while True:
#code which iterates my simulation
if condition: break

wat quite normal. This is the style loop I am using.


I think it's a bit abnormal, because you have to scan the loop body
for breaks. I tend to write:

condition = True
while not condition:
#code which iterates my simulation

But that's just me.

<mike
--
Mike Meyer <mw*@mired.or g> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Jul 18 '05 #9
>>>>> "Mike" == Mike Meyer <mw*@mired.or g> writes:

Mike> I think it's a bit abnormal, because you have to scan the
Mike> loop body for breaks. I tend to write:

Mike> condition = True
Mike> while condition: # corrected
Mike> #code which iterates my simulation

Then you'd have to scan the loop body to find the location where
condition is set, which is more difficult than locating breaks
normally. If you get a break, you really breaks. If you set
condition to False, you still might be modifying it to True later in
your code. And of course, most editors will highlight the "break" for
you, while no editor will highlight for you the "condition" variable
that you are staring at.

Regards,
Isaac.
Jul 18 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
2682
by: Francis Avila | last post by:
A little annoyed one day that I couldn't use the statefulness of generators as "resumable functions", I came across Hettinger's PEP 288 (http://www.python.org/peps/pep-0288.html, still listed as open, even though it's at least a year old and Guido doesn't seem very hot on the idea). I'm not too sure of its ideas on raising exceptions in generators from outside (although it looks like it might be convenient in some cases), but being able...
8
2253
by: Timothy Fitz | last post by:
It seems to me that in python, generators are not truly coroutines. I do not understand why. What I see is that generators are used almost exclusively for generation of lists just-in-time. Side effects are frowned upon. Coroutines, in contrast, are like split functions where side effects are often as important or more important than return values. I am currently writing a real time strategy game where I have visual effects and use...
3
1946
by: Carlos Ribeiro | last post by:
As a side track of my latest investigations, I began to rely heavily on generators for some stuff where I would previsouly use a more conventional approach. Whenever I need to process a list, I'm tending towards the use of generators. One good example is if I want to print a report, or to work over a list with complex processing for each item. In both cases, a simple list comprehension can't be used. The conventional approach involves...
9
2132
by: kosh | last post by:
I was wondering if there is or there could be some way to pass a generator an optional starting index so that if it supported that slicing could be made more efficient. Right now if you do use a generator and do a or any other kind of slice it reads all the values up to 100 also. I know a lot of generators have to do all previous parts before they can do the next part but it would be a nice optimization that can start at any index to...
24
3946
by: Lasse Vågsæther Karlsen | last post by:
I need to merge several sources of values into one stream of values. All of the sources are sorted already and I need to retrieve the values from them all in sorted order. In other words: s1 = s2 = s3 = for value in ???(s1, s2, s3):
6
4528
by: Talin | last post by:
I've been using generators to implement backtracking search for a while now. Unfortunately, my code is large and complex enough (doing unification on math expressions) that its hard to post a simple example. So I decided to look for a simpler problem that could be used to demonstrate the technique that I am talking about. I noticed that PEP 255 (Simple Generators) refers to an implementation of the "8 Queens" problem in the lib/test...
5
1193
by: Kenneth McDonald | last post by:
I recently had need to write the following code: def compileOuter(self): if False: yield None else: return "compileOuter" is a generator function which is implemented in various classes. In this particular class, it always yields nothing. However, none of the following work:
2
1315
by: Tom Sheffler | last post by:
This may have been discussed before, so I apologize. Does Java have generators? I am aware of the "Iterator" interface, but it seems much more restrictive. Python generators are useful for many more things than simply list enumeration, but the Java Iterator seems limited. Tom
12
1610
by: Wolfgang Keller | last post by:
Hello, in <dr86uc$8kt$1@wake.carmen.se>, Magnus Lycka <lycka@carmen.se> posts the result of a short test that seems to indicate that resuming a generator takes more time than calling a function. If this is actually also true in the general case, and not due to eventual non-representativeness of the test mentioned above, is it simply due to a less-than-optimum implementation of generators in the current Pyython interpreter and thus...
0
8465
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8383
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8894
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8803
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8587
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8658
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
4384
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2792
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2029
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.