Используется для отправки значений в генератор, который только что дал. Вот пример (не полезный):
>>> def double_inputs():
... while True:
... x = yield
... yield x * 2
...
>>> gen = double_inputs()
>>> next(gen) # run up to the first yield
>>> gen.send(10) # goes into 'x' variable
20
>>> next(gen) # run up to the next yield
>>> gen.send(6) # goes into 'x' again
12
>>> next(gen) # run up to the next yield
>>> gen.send(94.3) # goes into 'x' again
188.5999999999999
Вы не можете сделать это только с помощью yield
.
Что касается того, почему это полезно, один из лучшие примеры использования, которые я видел, это Twisted's @defer.inlineCallbacks
. По сути, это позволяет вам написать такую функцию:
@defer.inlineCallbacks
def doStuff():
result = yield takesTwoSeconds()
nextResult = yield takesTenSeconds(result * 10)
defer.returnValue(nextResult / 10)
Что происходит, так это то, что takesTwoSeconds()
возвращает Deferred
, что является значением, обещающим, что значение будет вычислено позже. Twisted может выполнять вычисления в другом потоке. Когда вычисление выполняется, оно передает его в отложенное, а затем значение возвращается к функции doStuff()
. Таким образом, doStuff()
может оказаться более или менее похожей на обычную процедурную функцию, за исключением того, что она может выполнять всевозможные вычисления и amp; обратные вызовы и т. д. Альтернативой перед этой функциональностью было бы сделать что-то вроде:
def doStuff():
returnDeferred = defer.Deferred()
def gotNextResult(nextResult):
returnDeferred.callback(nextResult / 10)
def gotResult(result):
takesTenSeconds(result * 10).addCallback(gotNextResult)
takesTwoSeconds().addCallback(gotResult)
return returnDeferred
Это намного сложнее и громоздко.
Когда вы используете Repeater, убедитесь, что весь ваш контент находится в узле шаблона, например <ItemTemplate>
- даже вложенный Repeater.
Как только разметка верна, вы можете прикрепить событие OnItemDataBound
к родительскому повторителю, затем использовать идентификатор этого элемента, чтобы получить данные для привязки к вложенному повторителю, а затем просто связать его. Например:
ASPX
<asp:Repeater ID="R1" runat="server" OnItemDataBound="R1_ItemDataBound">
<ItemTemplate>
<asp:HiddenField runat="server" ID="CompanyId" value='<%# Eval("id") %>' />
<div>name:<%# Eval("companyname") %></div>
<asp:Repeater ID="R2" runat="server">
<ItemTemplate>
ID :<%# Eval("companyid") %><br>
Name:<%# Eval("companyname") %>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
CS
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
DataTable dtx = Getparentfirm();
R1.DataSource = dtx;
R1.DataBind();
}
}
protected void R1_ItemDataBound(Object Sender, RepeaterItemEventArgs e) {
// Get companyId from hidden field
// or you could get it from e.Item.DataItem which should have the data for this row of data
var CompanyID = (HiddenField)e.Item.FindControl("CompanyId");
var id = Convert.ToInt32(CompanyID.Value);
var R2 = (Repeater)e.Item.FindControl("R2");
var dso = GetData(id); // Get sub companies based on this company id
R2.DataSource = dso;
R2.DataBind();
}
Что-то в этом роде