{ "cells": [ { "cell_type": "markdown", "id": "5ca1eb7e", "metadata": {}, "source": [ "使用用户输入\n", "===========" ] }, { "cell_type": "markdown", "id": "ec21fc25", "metadata": {}, "source": [ "在笔记本中,能够向用户询问某些值通常很有用。查询参数、身份验证令牌和文件路径是用于参数化笔记本的常见信息示例,以便在不同数据或不同用户之间重用它。\n", "有几种不同的方法可以避免在笔记本中硬编码这些值。" ] }, { "cell_type": "markdown", "id": "42e3f192", "metadata": {}, "source": [ "## 魔术命令中的输入提示" ] }, { "cell_type": "markdown", "id": "b938b023", "metadata": {}, "source": [ "在任何魔术命令中,您都可以使用@input标记代替特定值提示用户输入参数值。这将适用于任何魔法命令。\n", "\n", "比如:在共享变量命令 `#!set` 中:" ] }, { "cell_type": "code", "execution_count": 1, "id": "13dc837c", "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "用记输入内容为:小明\r\n" ] } ], "source": [ "#!set --name userInput --value @input(\"请输入姓名\")\n", "\n", "Console.WriteLine($\"用记输入内容为:{userInput}\");" ] }, { "cell_type": "markdown", "id": "49d3e40a", "metadata": {}, "source": [ "运行上面单元格时,VS Code窗口顶部会显示一个输入提示\n", "![输入提示](./assets/images/用户输入.jpg)" ] }, { "cell_type": "markdown", "id": "2ea86d1a", "metadata": {}, "source": [ "如果填写一个值并按Enter键,则该值将传递给相应的魔术命令参数。在这个例子中,可以在变量视图中看到输入的值:\n", "![输入提示](./assets/images/用户输入2.jpg)" ] }, { "cell_type": "markdown", "id": "bcf98c06", "metadata": {}, "source": [ "There are a few ways that you can customize the behavior of an @input or @password. (The following examples use @input but all of these will also work with @password.)\n", "有几种方法可以自定义`@input`或`@paswword`的行为。(以下示例使用@input,但所有这些示例也适用于@password)" ] }, { "cell_type": "markdown", "id": "995eb463", "metadata": {}, "source": [ "### 指定提示词" ] }, { "cell_type": "markdown", "id": "e5d5d059", "metadata": {}, "source": [ "可以使用以下任一语法自定义用户提示。这两个示例都显示了相同的提示:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "输入的值是:abc\n", "输入的值是:233\n" ] } ], "source": [ "#!set --name myVariable --value @input:\"请输入一个值\"\n", "Console.WriteLine($\"输入的值是:{myVariable}\");\n", "\n", "#!set --name myVariable2 --value @input:{\"prompt\": \"请输入一个值\"}\n", "Console.WriteLine($\"输入的值是:{myVariable2}\");" ] }, { "cell_type": "markdown", "id": "4224976b", "metadata": {}, "source": [ "第一个例子是第二个例子的简写。自定义@input行为的其他方式将遵循第二种模式,使用JSON传递参数。" ] }, { "cell_type": "markdown", "id": "37494b83", "metadata": {}, "source": [ "### 保存输入值" ] }, { "cell_type": "markdown", "id": "239dd8f4", "metadata": {}, "source": [ "有时,`@input`的值对于给定的用户来说不会随着时间的推移而改变。但是关闭并重新打开笔记本电脑或重新启动内核会导致内存状态丢失,如果您将用于给定`@input`的值每次都是相同的,您可以选择保存该值,这样您就不必不断重新输入它。\n", "\n", "要重用输入的值,可以在`@input`参数中指定saveAs属性:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [ { "data": { "text/markdown": [ "Using previously saved value for `此配置值只输入一次`.\r\n", "\r\n", "> 💡 To remove this value from your [SecretStore](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.secretstore/?view=ps-modules), run the following command in a PowerShell cell:\r\n", "> \r\n", "> ```powershell\r\n", "> Remove-Secret -Name \"此配置值只输入一次\" -Vault DotnetInteractive\r\n", "> ```\r\n", "\r\n", "> 📝 For more information, see [SecretManagement](https://learn.microsoft.com/en-us/powershell/utility-modules/secretmanagement/overview?view=ps-modules)." ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#!set --name myConfigFile --value @input:{\"saveAs\": \"此配置值只输入一次\"}" ] }, { "cell_type": "markdown", "id": "e0785682", "metadata": {}, "source": [ "当这个@input第一次运行时,它将像往常一样产生一个提示。\n", "\n", "然而,输出将指示该值已存储以供将来重用,并包括在以后想要更改时重置此值的说明。\n", "\n", "下次运行包含输入提示且saveAs设置为该名称的单元格时,将不会显示提示。将使用之前保存的值,并显示提醒消息以表明这一点:\n", "![保存输入](./assets/images/用户输入3.jpg)" ] }, { "cell_type": "markdown", "id": "eca381d9", "metadata": {}, "source": [ "此功能由PowerShell SecretManagement和SecretStore模块提供支持。它将把值安全地存储在运行PowerShell内核的计算机上。对于大多数用例,这将是您的本地计算机,但例如,如果您使用GitHub CodeSpaces运行笔记本电脑,则该值将存储在运行开发容器的VM上,这意味着当VM被回收时,该值将消失。" ] }, { "cell_type": "markdown", "id": "b5e7b0b1", "metadata": {}, "source": [ "### 键入提示" ] }, { "cell_type": "markdown", "id": "d47ccad7", "metadata": {}, "source": [ "为@input标记提供的所有值都是字符串,但有时对于您希望在笔记本中接收的字符串类型,可以使用更符合人体工程学的UI。\n", "\n", "例如,如果您期望的是现有文件的有效路径,那么文件选择器将提供比纯文本输入更好的体验。\n", "\n", "这是通过@input参数上的type属性来支持的。" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [], "source": [ "#!set --name myConfigFile --value @input:{\"type\": \"file\"}" ] }, { "cell_type": "markdown", "id": "3469d0b8", "metadata": {}, "source": [ "在这个例子中,显示的不是VS Code窗口顶部的文本输入框,而是一个文件对话框。\n", "![文件输入](./assets/images/用户输入4.jpg)" ] }, { "cell_type": "markdown", "id": "55d579cd", "metadata": {}, "source": [ "单个输入支持的输入类型目前仅限于文本和文件,但当单个魔术命令中存在多个输入时,可以使用其他类型,如下一节所述。" ] }, { "cell_type": "markdown", "id": "ba8b54a0", "metadata": {}, "source": [ "### 多输入" ] }, { "cell_type": "markdown", "id": "7b53676c", "metadata": {}, "source": [ "当一个魔术命令中有多个@input或@password标记时,单元格的输出区域会显示一个表单,每个表单都有字段。这里有一个例子:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [ { "data": { "text/html": [ "


" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#!set --name @input:{\"prompt\": \"请输入颜色名\"} --value @input:{\"type\": \"color\", \"prompt\": \"选择一种颜色,可以是任何颜色\"}" ] }, { "cell_type": "markdown", "id": "093477fc", "metadata": {}, "source": [ "请注意,前面的所有@input自定义都是可用的。在这个例子中,您可以看到显示了一个颜色选择器,因为@input小部件的type属性被设置为color。\n", "支持所有标准HTML输入类型。" ] }, { "cell_type": "markdown", "id": "7d5b910f", "metadata": {}, "source": [ "## 在.net core 代码中使用 用户输入" ] }, { "cell_type": "markdown", "id": "65883b66", "metadata": {}, "source": [ "也可以在.NET代码直接提示用户输入,而不是使用魔术命令。以下是C#中提示单个输入的示例:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "本次输入的是:333\r\n" ] } ], "source": [ "using Microsoft.DotNet.Interactive;\n", "\n", "var input_2 = await Kernel.GetInputAsync(\"输入一个数字.\");\n", "\n", "Console.WriteLine($\"本次输入的是:{input_2}\");" ] }, { "cell_type": "markdown", "id": "0261dc3b", "metadata": {}, "source": [ "生成的提示看起来与在magic命令中使用@input时显示的提示相同。\n", "\n", "还可以使用此API提供类型提示,web视图可以使用此提示来显示更具体的UI。\n" ] }, { "cell_type": "code", "execution_count": 7, "id": "b3c17736", "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [], "source": [ "using Microsoft.DotNet.Interactive;\n", "\n", "var input = await Kernel.GetInputAsync(\n", " \"Please pick a file.\",\n", " typeHint: \"file\");" ] }, { "cell_type": "markdown", "id": "a92ed4ed", "metadata": {}, "source": [ "如果类型提示是前端可以理解的,您将看到相应的弹窗;\n", "\n", "否则,它将退回到简单的文本输入。" ] }, { "cell_type": "markdown", "id": "35b5fdf0", "metadata": {}, "source": [ "### 密码和其他秘密" ] }, { "cell_type": "markdown", "id": "e75b088a", "metadata": {}, "source": [ "有些笔记本输入很敏感,你不希望它们以可读的形式保存在笔记本的代码单元格或输出中。\n", "您可以使用 `Kernel.GetPasswordAsync`" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [], "source": [ "using Microsoft.DotNet.Interactive;\n", "\n", "var input = await Kernel.GetPasswordAsync(\"请输入一个连接字符串\");" ] }, { "cell_type": "markdown", "id": "a3c3f0c2", "metadata": {}, "source": [ "### 命令行参数输入" ] }, { "cell_type": "markdown", "id": "08546388", "metadata": {}, "source": [ "[本节描述了未来可能添加到核心.NET Interactive产品中的实验功能。]\n", "\n", "笔记本电脑提示用户输入的功能解决了许多问题。但在自动化场景中(例如将笔记本电脑用作自动化工具或运行笔记本电脑的测试),没有用户在场来响应提示。\n", "\n", "这个。NET REPL具有从命令行运行笔记本的功能,无需UI或用户。为了能够为已知输入提供值。NET REPL可以识别magics中的@input:-前缀标记,并允许您在命令行传递这些输入的值。\n", "\n", "通过运行以下命令并将路径传递给笔记本,可以找出笔记本需要哪些参数。(这适用于.ipynb和.dib文件。)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "polyglot_notebook": { "kernelName": "pwsh" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "可能造成此问题的原因包括:\n", " *内置 dotnet 命令拼写错误。\n", " *你打算执行 .NET 程序,但 dotnet-repl 不存在。\n", " *你打算运行全局工具,但在 PATH 上找不到具有此名称且带有 dotnet 前缀的可执行文件。\n", "\u001b[31;1m无法执行,因为找不到指定的命令或文件。\u001b[0m\n" ] } ], "source": [ "dotnet repl describe /path/to/notebook.ipynb" ] }, { "cell_type": "markdown", "id": "0eb5cc53", "metadata": {}, "source": [ "dotnet repl-descripte 命令将显示笔记本所需的参数,并显示如何使用命令行选项传递它们的示例:\n", "\n", "![命令行输入](./assets/images/用户输入5.png)\n" ] } ], "metadata": { "kernelspec": { "display_name": ".NET (C#)", "language": "C#", "name": ".net-csharp" }, "polyglot_notebook": { "kernelInfo": { "defaultKernelName": "csharp", "items": [ { "aliases": [], "languageName": "csharp", "name": "csharp" } ] } } }, "nbformat": 4, "nbformat_minor": 5 }