1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/generator.R
\name{py_iterator}
\alias{py_iterator}
\title{Create a Python iterator from an R function}
\usage{
py_iterator(fn, completed = NULL, prefetch = 0L)
}
\arguments{
\item{fn}{R function with no arguments.}
\item{completed}{Special sentinel return value which indicates that
iteration is complete (defaults to \code{NULL}).}
\item{prefetch}{Number items to prefetch. Set this to a positive integer to
avoid a deadlock in situations where the generator values are consumed by
python background threads while the main thread is blocked.}
}
\value{
Python iterator which calls the R function for each iteration.
}
\description{
Create a Python iterator from an R function
}
\details{
Python generators are functions that implement the Python iterator
protocol. In Python, values are returned using the \code{yield} keyword. In R,
values are simply returned from the function.
In Python, the \code{yield} keyword enables successive iterations to use the state
of previous iterations. In R, this can be done by returning a function that
mutates its enclosing environment via the \verb{<<-} operator. For example:
\if{html}{\out{<div class="sourceCode r">}}\preformatted{sequence_generator <- function(start) \{
value <- start
function() \{
value <<- value + 1
value
\}
\}
}\if{html}{\out{</div>}}
Then create an iterator using \code{py_iterator()}:
\if{html}{\out{<div class="sourceCode r">}}\preformatted{g <- py_iterator(sequence_generator(10))
}\if{html}{\out{</div>}}
}
\section{Ending Iteration}{
In Python, returning from a function without calling \code{yield} indicates the
end of the iteration. In R however, \code{return} is used to yield values, so
the end of iteration is indicated by a special return value (\code{NULL} by
default, however this can be changed using the \code{completed} parameter). For
example:
\if{html}{\out{<div class="sourceCode r">}}\preformatted{sequence_generator <-function(start) \{
value <- start
function() \{
value <<- value + 1
if (value < 100)
value
else
NULL
\}
\}
}\if{html}{\out{</div>}}
}
\section{Threading}{
Some Python APIs use generators to parallellize operations by calling the
generator on a background thread and then consuming its results on
the foreground thread. The \code{py_iterator()} function creates threadsafe
iterators by ensuring that the R function is always called on the main
thread (to be compatible with R's single-threaded runtime) even if the
generator is run on a background thread.
}
|