{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 格式字符串字面值\n",
    "\n",
    "格式字符串字面值 或称 f-string 是标注了 `'f'` 或 `'F'` 前缀的字符串字面值。这种字符串可包含替换字段，即以 `{}` 标注的表达式。其他字符串字面值只是常量，格式字符串字面值则是可在运行时求值的表达式。\n",
    "\n",
    "句法格式：\n",
    "\n",
    "```{eval-rst}\n",
    ".. productionlist:: python-grammar\n",
    "   f_string: (`literal_char` | \"{{\" | \"}}\" | `replacement_field`)*\n",
    "   replacement_field: \"{\" `f_expression` [\"=\"] [\"!\" `conversion`] [\":\" `format_spec`] \"}\"\n",
    "   f_expression: (`conditional_expression` | \"*\" `or_expr`)\n",
    "               :   (\",\" `conditional_expression` | \",\" \"*\" `or_expr`)* [\",\"]\n",
    "               : | `yield_expression`\n",
    "   conversion: \"s\" | \"r\" | \"a\"\n",
    "   format_spec: (`literal_char` | NULL | `replacement_field`)*\n",
    "   literal_char: <any code point except \"{\", \"}\" or NULL>\n",
    "```\n",
    "\n",
    "除非字面值标记为原始字符串，否则，与在普通字符串字面值中一样，转义序列也会被解码。\n",
    "\n",
    "- 双花括号 `'{{'` 或 `'}}'` 被替换为单花括号，花括号外的字符串仍按字面值处理。\n",
    "- 单左花括号 `'{'` 标记以 Python 表达式开头的替换字段。替换字段以右花括号 `'}'` 为结尾。\n",
    "- 在表达式后加等于号 `'='`，可在求值后，同时显示表达式文本及其结果（用于调试）。 \n",
    "- 用叹号 `'!'` 标记的转换字段。\n",
    "- 还可以在冒号 `':'` 后附加格式说明符。\n",
    "- 指定了转换符时，表达式求值的结果会先转换，再格式化。转换符 `'!s'` 调用 {func}`str` 转换求值结果，`'!r'` 调用 {func}`repr`，`'!a'` 调用 {func}`ascii`。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"He said his name is 'Fred'.\""
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "name = \"Fred\"\n",
    "f\"He said his name is {name!r}.\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"He said his name is 'Fred'.\""
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"He said his name is {repr(name)}.\"  # repr() is equivalent to !r"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'result:      12.35'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import decimal\n",
    "width = 10\n",
    "precision = 4\n",
    "value = decimal.Decimal(\"12.34567\")\n",
    "f\"result: {value:{width}.{precision}}\"  # nested fields"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'January 27, 2017'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from datetime import datetime\n",
    "\n",
    "today = datetime(year=2017, month=1, day=27)\n",
    "f\"{today:%B %d, %Y}\"  # using date format specifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'today=January 27, 2017'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"{today=:%B %d, %Y}\" # using date format specifier and debugging"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'0x400'"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "number = 1024\n",
    "f\"{number:#0x}\"  # using integer format specifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\" foo = 'bar'\""
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "foo = \"bar\"\n",
    "f\"{ foo = }\" # preserves whitespace"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'line = \"The mill\\'s closed\"'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "line = \"The mill's closed\"\n",
    "f\"{line = }\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"line = The mill's closed   \""
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"{line = :20}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'line = \"The mill\\'s closed\" '"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"{line = !r:20}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "681b3f0bf9b1b90d6d0c88f7c199d2184ced41189915c665b64d57703d01fa88"
  },
  "kernelspec": {
   "display_name": "Python 3.9.7 64-bit ('hs': conda)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
