{"id":9161,"date":"2024-02-22T09:31:49","date_gmt":"2024-02-22T01:31:49","guid":{"rendered":"\/?p=9161"},"modified":"2024-02-22T09:31:49","modified_gmt":"2024-02-22T01:31:49","slug":"%e5%87%a0%e4%b8%aa%e8%a2%ab%e6%b7%98%e6%b1%b0%e7%9a%84-python-%e5%ba%93%ef%bc%8c%e8%af%b7%e4%b8%8d%e8%a6%81%e5%86%8d%e7%94%a8%ef%bc%81","status":"publish","type":"post","link":"\/?p=9161","title":{"rendered":"\u51e0\u4e2a\u88ab\u6dd8\u6c70\u7684 Python \u5e93\uff0c\u8bf7\u4e0d\u8981\u518d\u7528\uff01"},"content":{"rendered":"<p>\u968f\u7740\u6bcf\u4e2a Python \u7248\u672c\u7684\u53d1\u5e03\uff0c\u90fd\u4f1a\u6dfb\u52a0\u65b0\u6a21\u5757\uff0c\u5e76\u5f15\u5165\u65b0\u7684\u66f4\u597d\u7684\u505a\u4e8b\u65b9\u5f0f\uff0c\u867d\u7136\u6211\u4eec\u90fd\u4e60\u60ef\u4e86\u4f7f\u7528\u597d\u7684\u65e7 Python \u5e93\u548c\u67d0\u4e9b\u505a\u4e8b\u65b9\u5f0f\uff0c\u4f46\u73b0\u5728\u4e5f\u65f6\u5019\u5347\u7ea7\u5e76\u5229\u7528\u65b0\u7684\u548c\u6539\u8fdb\u7684\u6a21\u5757\u53ca\u5176\u7279\u6027\u4e86\u3002<\/p>\n<h2>Pathlib \u800c\u4e0d\u662f OS<\/h2>\n<p>pathlib \u7edd\u5bf9\u662f Python \u6807\u51c6\u5e93\u4e2d\u6700\u8fd1\u6dfb\u52a0\u7684\u66f4\u5927\u7684\u5185\u5bb9\u4e4b\u4e00\uff0c \u81ea Python 3.4 \u4ee5\u6765\uff0c\u5b83\u4e00\u76f4\u662f\u6807\u51c6\u5e93\u7684\u4e00\u90e8\u5206\uff0c\u4f46\u5f88\u591a\u4eba\u4ecd\u7136\u4f7f\u7528 os \u6a21\u5757\u8fdb\u884c\u6587\u4ef6\u7cfb\u7edf\u64cd\u4f5c\u3002<\/p>\n<p>\u7136\u800c\uff0cpathlib \u4e0e\u65e7\u7684 os.path \u76f8\u6bd4\u5177\u6709\u8bb8\u591a\u4f18\u70b9 - \u867d\u7136 os \u6a21\u5757\u4ee5\u539f\u59cb\u5b57\u7b26\u4e32\u683c\u5f0f\u8868\u793a\u8def\u5f84\uff0c\u4f46 pathlib \u4f7f\u7528\u9762\u5411\u5bf9\u8c61\u7684\u6837\u5f0f\uff0c\u8fd9\u4f7f\u5f97\u5b83\u66f4\u5177\u53ef\u8bfb\u6027\u548c\u7f16\u5199\u81ea\u7136\uff1a<\/p>\n<pre><code class=\"language-python\">from pathlib import Path\nimport os.path\n\n# \u8001\u65b9\u5f0f\ntwo_dirs_up = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n# \u65b0\u65b9\u5f0f\uff0c\u53ef\u8bfb\u6027\u5f3a\ntwo_dirs_up = Path(__file__).resolve().parent.parent<\/code><\/pre>\n<p>\u8def\u5f84\u88ab\u89c6\u4e3a\u5bf9\u8c61\u800c\u4e0d\u662f\u5b57\u7b26\u4e32\u8fd9\u4e00\u4e8b\u5b9e\u4e5f\u4f7f\u5f97\u53ef\u4ee5\u521b\u5efa\u4e00\u6b21\u5bf9\u8c61\uff0c\u7136\u540e\u67e5\u627e\u5176\u5c5e\u6027\u6216\u5bf9\u5176\u8fdb\u884c\u64cd\u4f5c\uff1a<\/p>\n<pre><code class=\"language-python\">readme = Path(&quot;README.md&quot;).resolve()\n\nprint(f&quot;Absolute path: {readme.absolute()}&quot;)\n# Absolute path: \/home\/martin\/some\/path\/README.md\nprint(f&quot;File name: {readme.name}&quot;)\n# File name: README.md\nprint(f&quot;Path root: {readme.root}&quot;)\n# Path root: \/\nprint(f&quot;Parent directory: {readme.parent}&quot;)\n# Parent directory: \/home\/martin\/some\/path\nprint(f&quot;File extension: {readme.suffix}&quot;)\n# File extension: .md\nprint(f&quot;Is it absolute: {readme.is_absolute()}&quot;)\n# Is it absolute: True<\/code><\/pre>\n<p>\u6211\u6700\u559c\u6b22 pathlib \u7684\u4e00\u4e2a\u7279\u6027\u662f\u53ef\u4ee5\u4f7f\u7528 \/\uff08\u201c\u9664\u6cd5\u201d\uff09\u8fd0\u7b97\u7b26\u6765\u8fde\u63a5\u8def\u5f84\uff1a<\/p>\n<pre><code class=\"language-python\"># Operators:\netc = Path(&#039;\/etc&#039;)\n\njoined = etc \/ &quot;cron.d&quot; \/ &quot;anacron&quot;\nprint(f&quot;Exists? - {joined.exists()}&quot;)\n# Exists? - True<\/code><\/pre>\n<p>\u91cd\u8981\u7684\u662f\u8981\u6ce8\u610f pathlib \u53ea\u662f\u66ff\u4ee3 os.path \u800c\u4e0d\u662f\u6574\u4e2a os \u6a21\u5757\uff0c \u5b83\u8fd8\u5305\u62ec glob \u6a21\u5757\u7684\u529f\u80fd\uff0c\u56e0\u6b64\u5982\u679c\u4f60\u4e60\u60ef\u4e8e\u5c06 os.path \u4e0e glob.glob \u7ed3\u5408\u4f7f\u7528\uff0c\u90a3\u4e48\u4f60\u53ef\u4ee5\u5b8c\u5168\u7528pathlib\u66ff\u4ee3\u5b83\u4eec\u3002<\/p>\n<p>\u5728\u4e0a\u9762\u7684\u7247\u6bb5\u4e2d\uff0c\u6211\u4eec\u5c55\u793a\u4e86\u4e00\u4e9b\u65b9\u4fbf\u7684\u8def\u5f84\u64cd\u4f5c\u548c\u5bf9\u8c61\u5c5e\u6027\uff0c\u4f46 pathlib \u8fd8\u5305\u62ec\u4f60\u4e60\u60ef\u4e8e os.path \u7684\u6240\u6709\u65b9\u6cd5\uff0c\u4f8b\u5982\uff1a<\/p>\n<pre><code class=\"language-python\">print(f&quot;Working directory: {Path.cwd()}&quot;)  # same as os.getcwd()\n# Working directory: \/home\/martin\/some\/path\nPath.mkdir(Path.cwd() \/ &quot;new_dir&quot;, exist_ok=True)  # same as os.makedirs()\nprint(Path(&quot;README.md&quot;).resolve())  # same as os.path.abspath()\n# \/home\/martin\/some\/path\/README.md\nprint(Path.home())  # same as os.path.expanduser()\n# \/home\/martin<\/code><\/pre>\n<p>\u6709\u5173 os.path \u51fd\u6570\u5230 pathlib \u4e2d\u65b0\u51fd\u6570\u7684\u5b8c\u6574\u6620\u5c04\uff0c\u8bf7\u53c2\u9605 \u5b98\u65b9\u6587\u6863\u3002<\/p>\n<h2>Secrets \u800c\u4e0d\u662f OS<\/h2>\n<p>\u8bf4\u5230 os \u6a21\u5757\uff0c\u4f60\u5e94\u8be5\u505c\u6b62\u4f7f\u7528\u7684\u53e6\u4e00\u90e8\u5206\u662f os.urandom\u3002\u76f8\u53cd\uff0c\u4f60\u5e94\u8be5\u4f7f\u7528\u81ea Python 3.6 \u4ee5\u6765\u53ef\u7528\u7684\u65b0\u79d8\u5bc6\u6a21\u5757\uff1a<\/p>\n<pre><code class=\"language-python\"># \u8001\u65b9\u5f0f:\nimport os\n\nlength = 64\n\nvalue = os.urandom(length)\nprint(f&quot;Bytes: {value}&quot;)\n# Bytes: b&#039;\\xfa\\xf3...\\xf2\\x1b\\xf5\\xb6&#039;\nprint(f&quot;Hex: {value.hex()}&quot;)\n# Hex: faf3cc656370e31a938e7...33d9b023c3c24f1bf5\n\n# \u65b0\u65b9\u5f0f:\nimport secrets\n\nvalue = secrets.token_bytes(length)\nprint(f&quot;Bytes: {value}&quot;)\n# Bytes: b&#039;U\\xe9n\\x87...\\x85&gt;\\x04j:\\xb0&#039;\nvalue = secrets.token_hex(length)\nprint(f&quot;Hex: {value}&quot;)\n# Hex: fb5dd85e7d73f7a08b8e3...4fd9f95beb08d77391<\/code><\/pre>\n<p>\u4f7f\u7528 os.urandom \u5b9e\u9645\u4e0a\u5e76\u4e0d\u662f\u8fd9\u91cc\u7684\u95ee\u9898\uff0c\u5f15\u5165secrets\u6a21\u5757\u7684\u539f\u56e0\u662f\u56e0\u4e3a\u4eba\u4eec\u4f7f\u7528\u968f\u673a\u6a21\u5757\u6765\u751f\u6210\u5bc6\u7801\u7b49\uff0c\u5373\u4f7f\u968f\u673a\u6a21\u5757\u4e0d\u4ea7\u751f\u5bc6\u7801\u5b89\u5168\u4ee4\u724c\u3002<\/p>\n<p>\u6839\u636e\u6587\u6863\uff0c\u968f\u673a\u6a21\u5757\u4e0d\u5e94\u7528\u4e8e\u5b89\u5168\u76ee\u7684\uff0c \u4f60\u5e94\u8be5\u4f7f\u7528 secrets \u6216 os.urandom\uff0c\u4f46 secrets \u6a21\u5757\u7edd\u5bf9\u66f4\u53ef\u53d6\uff0c\u56e0\u4e3a\u5b83\u6bd4\u8f83\u65b0\uff0c\u5e76\u4e14\u5305\u542b\u4e00\u4e9b\u7528\u4e8e\u5341\u516d\u8fdb\u5236\u4ee4\u724c\u7684\u5b9e\u7528\u7a0b\u5e8f\/\u4fbf\u5229\u65b9\u6cd5\u4ee5\u53ca URL \u5b89\u5168\u4ee4\u724c\u3002<\/p>\n<h2>Zoneinfo \u800c\u4e0d\u662f pytz<\/h2>\n<p>\u5728 Python 3.9 \u4e4b\u524d\uff0c\u6ca1\u6709\u7528\u4e8e\u65f6\u533a\u64cd\u4f5c\u7684\u5185\u7f6e\u5e93\uff0c\u6240\u4ee5\u6bcf\u4e2a\u4eba\u90fd\u5728\u4f7f\u7528 pytz\uff0c\u4f46\u73b0\u5728\u6211\u4eec\u5728\u6807\u51c6\u5e93\u4e2d\u6709 zoneinfo\uff0c\u6240\u4ee5\u662f\u65f6\u5019\u5207\u6362\u4e86\u3002<\/p>\n<pre><code class=\"language-python\">from datetime import datetime\nimport pytz  # pip install pytz\n\ndt = datetime(2022, 6, 4)\nnyc = pytz.timezone(&quot;America\/New_York&quot;)\n\nlocalized = nyc.localize(dt)\nprint(f&quot;Datetime: {localized}, Timezone: {localized.tzname()}, TZ Info: {localized.tzinfo}&quot;)\n\n# \u65b0\u65b9\u5f0f:\nfrom zoneinfo import ZoneInfo\n\nnyc = ZoneInfo(&quot;America\/New_York&quot;)\nlocalized = datetime(2022, 6, 4, tzinfo=nyc)\nprint(f&quot;Datetime: {localized}, Timezone: {localized.tzname()}, TZ Info: {localized.tzinfo}&quot;)\n# Datetime: 2022-06-04 00:00:00-04:00, Timezone: EDT, TZ Info: America\/New_York<\/code><\/pre>\n<p>datetime \u6a21\u5757\u5c06\u6240\u6709\u65f6\u533a\u64cd\u4f5c\u59d4\u6258\u7ed9\u62bd\u8c61\u57fa\u7c7b datetime.tzinfo\uff0c \u8fd9\u4e2a\u62bd\u8c61\u57fa\u7c7b\u9700\u8981\u4e00\u4e2a\u5177\u4f53\u7684\u5b9e\u73b0\u2014\u2014\u5728\u5f15\u5165\u8fd9\u4e2a\u5f88\u53ef\u80fd\u6765\u81ea pytz \u7684\u6a21\u5757\u4e4b\u524d\u3002\u73b0\u5728\u6211\u4eec\u5728\u6807\u51c6\u5e93\u4e2d\u6709 zoneinfo\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u5b83\u3002<\/p>\n<p>\u7136\u800c\uff0c\u4f7f\u7528 zoneinfo \u6709\u4e00\u4e2a\u8b66\u544a\u2014\u2014\u5b83\u5047\u5b9a\u7cfb\u7edf\u4e0a\u6709\u53ef\u7528\u7684\u65f6\u533a\u6570\u636e\uff0cUNIX \u7cfb\u7edf\u5c31\u662f\u8fd9\u79cd\u60c5\u51b5\uff0c \u5982\u679c\u4f60\u7684\u7cfb\u7edf\u6ca1\u6709\u65f6\u533a\u6570\u636e\uff0c\u90a3\u4e48\u4f60\u5e94\u8be5\u4f7f\u7528 tzdata \u5305\uff0c\u5b83\u662f\u7531 CPython \u6838\u5fc3\u5f00\u53d1\u4eba\u5458\u7ef4\u62a4\u7684\u7b2c\u4e00\u65b9\u5e93\uff0c\u5176\u4e2d\u5305\u542b IANA \u65f6\u533a\u6570\u636e\u5e93\u3002<\/p>\n<h2>Dataclasses<\/h2>\n<p>Python 3.7 \u7684\u4e00\u4e2a\u91cd\u8981\u8865\u5145\u662f dataclasses \u5305\uff0c\u5b83\u662f namedtuple \u7684\u66ff\u4ee3\u54c1\u3002<\/p>\n<p>\u4f60\u53ef\u80fd\u60f3\u77e5\u9053\u4e3a\u4ec0\u4e48\u9700\u8981\u66ff\u6362 namedtuple\uff1f\u4ee5\u4e0b\u662f\u4f60\u5e94\u8be5\u8003\u8651\u5207\u6362\u5230\u6570\u636e\u7c7b\u7684\u4e00\u4e9b\u539f\u56e0\uff1a<\/p>\n<ul>\n<li>1\u3001\u5b83\u53ef\u4ee5\u662f\u53ef\u53d8\u7684<\/li>\n<li>2\u3001\u9ed8\u8ba4\u63d0\u4f9b repr\u3001eq\u3001init\u3001hash \u9b54\u672f\u65b9\u6cd5\uff0c<\/li>\n<li>3\u3001\u5141\u8bb8\u6307\u5b9a\u9ed8\u8ba4\u503c\uff0c<\/li>\n<li>4\u3001\u652f\u6301\u7ee7\u627f\u3002\u6b64\u5916\uff0c\u6570\u636e\u7c7b\u8fd8\u652f\u6301 frozen \u548c slots\uff08\u4ece 3.10 \u5f00\u59cb\uff09\u5c5e\u6027\u4ee5\u63d0\u4f9b\u4e0e\u547d\u540d\u5143\u7ec4\u7684\u7279\u5f81\u5947\u5076\u6821\u9a8c\u3002<\/li>\n<\/ul>\n<p>\u5207\u6362\u771f\u7684\u4e0d\u5e94\u8be5\u592a\u96be\uff0c\u56e0\u4e3a\u4f60\u53ea\u9700\u8981\u66f4\u6539\u5b9a\u4e49\uff1a<\/p>\n<pre><code class=\"language-python\"># \u8001\u65b9\u5f0f:\n# from collections import namedtuple\nfrom typing import NamedTuple\nimport sys\n\nUser = NamedTuple(&quot;User&quot;, [(&quot;name&quot;, str), (&quot;surname&quot;, str), (&quot;password&quot;, bytes)])\n\nu = User(&quot;John&quot;, &quot;Doe&quot;, b&#039;tfeL+uD...\\xd2&#039;)\nprint(f&quot;Size: {sys.getsizeof(u)}&quot;)\n# Size: 64\n\n# \u65b0\u65b9\u5f0f:\nfrom dataclasses import dataclass\n\n@dataclass()\nclass User:\n   name: str\n   surname: str\n   password: bytes\n\nu = User(&quot;John&quot;, &quot;Doe&quot;, b&#039;tfeL+uD...\\xd2&#039;)\n\nprint(u)\n# User(name=&#039;John&#039;, surname=&#039;Doe&#039;, password=b&#039;tfeL+uD...\\xd2&#039;)\n\nprint(f&quot;Size: {sys.getsizeof(u)}, {sys.getsizeof(u) + sys.getsizeof(vars(u))}&quot;)\n# Size: 48, 152<\/code><\/pre>\n<p>\u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u8fd8\u5305\u542b\u4e86\u5927\u5c0f\u6bd4\u8f83\uff0c\u56e0\u4e3a\u8fd9\u662f namedtuple \u548c\u6570\u636e\u7c7b\u4e4b\u95f4\u7684\u8f83\u5927\u5dee\u5f02\u4e4b\u4e00\uff0c\u5982\u4e0a\u6240\u89c1\uff0c\u547d\u540d\u5143\u7ec4\u7684\u5927\u5c0f\u8981\u5c0f\u5f97\u591a\uff0c\u8fd9\u662f\u7531\u4e8e\u6570\u636e\u7c7b\u4f7f\u7528 dict \u6765\u8868\u793a\u5c5e\u6027\u3002<\/p>\n<p>\u81f3\u4e8e\u901f\u5ea6\u6bd4\u8f83\uff0c\u9664\u975e\u4f60\u8ba1\u5212\u521b\u5efa\u6570\u767e\u4e07\u4e2a\u5b9e\u4f8b\uff0c\u5426\u5219\u5c5e\u6027\u7684\u8bbf\u95ee\u65f6\u95f4\u5e94\u8be5\u57fa\u672c\u76f8\u540c\uff0c\u6216\u8005\u4e0d\u591f\u91cd\u8981\uff1a<\/p>\n<pre><code class=\"language-python\">import timeit\n\nsetup = &#039;&#039;&#039;\nfrom typing import NamedTuple\nUser = NamedTuple(&quot;User&quot;, [(&quot;name&quot;, str), (&quot;surname&quot;, str), (&quot;password&quot;, bytes)])\nu = User(&quot;John&quot;, &quot;Doe&quot;, b&#039;&#039;)\n&#039;&#039;&#039;\n\nprint(f&quot;Access speed: {min(timeit.repeat(&#039;u.name&#039;, setup=setup, number=10000000))}&quot;)\n# Access speed: 0.16838401100540068\n\nsetup = &#039;&#039;&#039;\nfrom dataclasses import dataclass\n\n@dataclass(slots=True)\nclass User:\n  name: str\n  surname: str\n  password: bytes\n\nu = User(&quot;John&quot;, &quot;Doe&quot;, b&#039;&#039;)\n&#039;&#039;&#039;\n\nprint(f&quot;Access speed: {min(timeit.repeat(&#039;u.name&#039;, setup=setup, number=10000000))}&quot;)\n# Access speed: 0.17728697300481144<\/code><\/pre>\n<p>\u5982\u679c\u4ee5\u4e0a\u5185\u5bb9\u8bf4\u670d\u4e86\u4f60\u6253\u7b97\u5207\u6362\u5230\u6570\u636e\u7c7b\uff0c\u8bf7\u5c3d\u5feb\u5c1d\u8bd5\u5427<\/p>\n<p>\u76f8\u53cd\uff0c\u5982\u679c\u4f60\u4e0d\u60f3\u5207\u6362\u5e76\u4e14\u51fa\u4e8e\u67d0\u79cd\u539f\u56e0\u771f\u7684\u60f3\u4f7f\u7528\u547d\u540d\u5143\u7ec4\uff0c\u90a3\u4e48\u4f60\u81f3\u5c11\u5e94\u8be5\u4f7f\u7528\u952e\u5165\u6a21\u5757\u800c\u4e0d\u662fcollections\u4e2d\u7684 NamedTuple\uff1a<\/p>\n<pre><code class=\"language-python\"># \u4e0d\u597d\u65b9\u5f0f\u7684:\nfrom collections import namedtuple\nPoint = namedtuple(&quot;Point&quot;, [&quot;x&quot;, &quot;y&quot;])\n\n# \u66f4\u597d\u7684\u65b9\u5f0f:\nfrom typing import NamedTuple\nclass Point(NamedTuple):\n    x: float\n    y: float<\/code><\/pre>\n<p>\u6700\u540e\uff0c\u5982\u679c\u4f60\u65e2\u4e0d\u4f7f\u7528 namedtuple \u4e5f\u4e0d\u4f7f\u7528\u6570\u636e\u7c7b\uff0c\u4f60\u53ef\u80fd\u9700\u8981\u8003\u8651\u76f4\u63a5\u4f7f\u7528 Pydantic\u3002<\/p>\n<h2>Proper Logging \u800c\u4e0d\u662f print<\/h2>\n<p>\u8fd9\u4e0d\u662f\u6807\u51c6\u5e93\u7684\u6700\u65b0\u6dfb\u52a0\uff0c\u4f46\u503c\u5f97\u4f7f\u7528 - \u4f60\u5e94\u8be5\u4f7f\u7528\u6b63\u786e\u7684\u65e5\u5fd7\u8bb0\u5f55\u800c\u4e0d\u662f\u6253\u5370\u8bed\u53e5\uff0c \u5982\u679c\u4f60\u5728\u672c\u5730\u8c03\u8bd5\u95ee\u9898\uff0c\u5219\u53ef\u4ee5\u4f7f\u7528 print\uff0c\u4f46\u5bf9\u4e8e\u4efb\u4f55\u65e0\u9700\u7528\u6237\u5e72\u9884\u5373\u53ef\u8fd0\u884c\u7684\u751f\u4ea7\u5c31\u7eea\u7a0b\u5e8f\uff0c\u6b63\u786e\u7684\u65e5\u5fd7\u8bb0\u5f55\u662f\u5fc5\u987b\u7684\u3002<\/p>\n<p>\u7279\u522b\u662f\u8003\u8651\u5230\u8bbe\u7f6e Python \u65e5\u5fd7\u8bb0\u5f55\u975e\u5e38\u7b80\u5355\uff1a<\/p>\n<pre><code class=\"language-python\">import logging\nlogging.basicConfig(\n    filename=&#039;application.log&#039;,\n    level=logging.WARNING,\n    format=&#039;[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s&#039;,\n    datefmt=&#039;%H:%M:%S&#039;\n)\n\nlogging.error(&quot;Some serious error occurred.&quot;)\n# [12:52:35] {&lt;stdin&gt;:1} ERROR - Some serious error occurred.\nlogging.warning(&#039;Some warning.&#039;)\n# [12:52:35] {&lt;stdin&gt;:1} WARNING - Some warning.<\/code><\/pre>\n<p>\u4e0e\u6253\u5370\u8bed\u53e5\u76f8\u6bd4\uff0c\u4e0a\u9762\u7684\u7b80\u5355\u914d\u7f6e\u5c06\u4e3a\u4f60\u63d0\u4f9b\u5353\u8d8a\u7684\u8c03\u8bd5\u4f53\u9a8c\uff0c \u6700\u91cd\u8981\u7684\u662f\uff0c\u4f60\u53ef\u4ee5\u8fdb\u4e00\u6b65\u81ea\u5b9a\u4e49\u65e5\u5fd7\u5e93\u4ee5\u8bb0\u5f55\u5230\u4e0d\u540c\u7684\u4f4d\u7f6e\u3001\u66f4\u6539\u65e5\u5fd7\u7ea7\u522b\u3001\u81ea\u52a8\u8f6e\u6362\u65e5\u5fd7\u7b49\u3002<\/p>\n<h2>f-strings \u800c\u4e0d\u662f format<\/h2>\n<p>Python \u5305\u542b\u5f88\u591a\u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u7684\u65b9\u6cd5\uff0c\u5305\u62ec C \u6837\u5f0f\u683c\u5f0f\u5316\u3001f \u5b57\u7b26\u4e32\u3001\u6a21\u677f\u5b57\u7b26\u4e32\u6216 .format \u51fd\u6570\uff0c \u4e0d\u8fc7\uff0c\u5176\u4e2d\u4e4b\u4e00 - f-strings - \u683c\u5f0f\u5316\u7684\u5b57\u7b26\u4e32\u6587\u5b57 \uff0c \u5b83\u4eec\u5199\u8d77\u6765\u66f4\u81ea\u7136\uff0c\u53ef\u8bfb\u6027\u66f4\u5f3a\uff0c\u5e76\u4e14\u662f\u524d\u9762\u63d0\u5230\u7684\u9009\u9879\u4e2d\u6700\u5feb\u7684\u3002<\/p>\n<p>\u56e0\u6b64\uff0c\u6211\u8ba4\u4e3a\u6ca1\u6709\u5fc5\u8981\u4e89\u8bba\u6216\u89e3\u91ca\u4e3a\u4ec0\u4e48\u8981\u4f7f\u7528\u5b83\u4eec\uff0c\u7136\u800c\uff0c\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\u4e0d\u80fd\u4f7f\u7528 f \u5b57\u7b26\u4e32\uff1a<\/p>\n<p>\u4f7f\u7528 % \u683c\u5f0f\u7684\u552f\u4e00\u539f\u56e0\u662f\u7528\u4e8e\u8bb0\u5f55\uff1a<\/p>\n<pre><code class=\"language-python\">import logging\n\nthings = &quot;something happened...&quot;\n\nlogger = logging.getLogger(__name__)\nlogger.error(&quot;Message: %s&quot;, things)  # \u8bc4\u4f30\u5185\u90e8\u8bb0\u5f55\u5668\u65b9\u6cd5\nlogger.error(f&quot;Message: {things}&quot;)  # \u7acb\u5373\u8bc4\u4f30<\/code><\/pre>\n<p>\u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c\u5982\u679c\u4f60\u4f7f\u7528 f \u5b57\u7b26\u4e32\uff0c\u5219\u8868\u8fbe\u5f0f\u5c06\u7acb\u5373\u8ba1\u7b97\uff0c\u800c\u4f7f\u7528 C \u6837\u5f0f\u683c\u5f0f\uff0c\u66ff\u6362\u5c06\u88ab\u63a8\u8fdf\u5230\u5b9e\u9645\u9700\u8981\u65f6\uff0c\u8fd9\u5bf9\u4e8e\u6d88\u606f\u5206\u7ec4\u5f88\u91cd\u8981\uff0c\u5176\u4e2d\u5177\u6709\u76f8\u540c\u6a21\u677f\u7684\u6240\u6709\u6d88\u606f\u90fd\u53ef\u4ee5\u8bb0\u5f55\u4e3a\u4e00\u4e2a\uff0c \u8fd9\u4e0d\u9002\u7528\u4e8e f \u5b57\u7b26\u4e32\uff0c\u56e0\u4e3a\u6a21\u677f\u5728\u4f20\u9012\u7ed9\u8bb0\u5f55\u5668\u4e4b\u524d\u586b\u5145\u4e86\u6570\u636e\u3002<\/p>\n<p>\u6b64\u5916\uff0c\u6709\u4e9b\u4e8b\u60c5\u662f f-strings \u6839\u672c\u65e0\u6cd5\u505a\u5230\u7684\uff0c \u4f8b\u5982\u5728\u8fd0\u884c\u65f6\u586b\u5145\u6a21\u677f - \u5373\u52a8\u6001\u683c\u5f0f - \u8fd9\u5c31\u662f f-strings \u88ab\u79f0\u4e3a\u6587\u5b57\u5b57\u7b26\u4e32\u683c\u5f0f\u7684\u539f\u56e0\uff1a<\/p>\n<pre><code class=\"language-python\"># \u52a8\u6001\u8bbe\u7f6e\u6a21\u677f\u53ca\u5176\u53c2\u6570\ndef func(tpl: str, param1: str, param2: str) -&gt; str:\n    return tpl.format(param=param1, param2=param2)\n\nsome_template = &quot;First template: {param1}, {param2}&quot;\nanother_template = &quot;Other template: {param1} and {param2}&quot;\nprint(func(some_template, &quot;Hello&quot;, &quot;World&quot;))\nprint(func(another_template, &quot;Hello&quot;, &quot;Python&quot;))\n\n# \u52a8\u6001\u91cd\u7528\u5177\u6709\u4e0d\u540c\u53c2\u6570\u7684\u76f8\u540c\u6a21\u677f.\ninputs = [&quot;Hello&quot;, &quot;World&quot;, &quot;!&quot;]\ntemplate = &quot;Here&#039;s some dynamic value: {value}&quot;\n\nfor value in inputs:\n    print(template.format(value=value))<\/code><\/pre>\n<p>\u6700\u91cd\u8981\u7684\u662f\uff0c\u5c3d\u53ef\u80fd\u4f7f\u7528 f \u5b57\u7b26\u4e32\uff0c\u56e0\u4e3a\u5b83\u4eec\u66f4\u5177\u53ef\u8bfb\u6027\u548c\u66f4\u9ad8\u6027\u80fd\uff0c\u4f46\u8bf7\u6ce8\u610f\uff0c\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\u4ecd\u7136\u9996\u9009\u548c\/\u6216\u9700\u8981\u5176\u4ed6\u683c\u5f0f\u6837\u5f0f\u3002<\/p>\n<h2>Tomllib \u800c\u4e0d\u662f tomli<\/h2>\n<p>TOML \u662f\u4e00\u79cd\u5e7f\u6cdb\u4f7f\u7528\u7684\u914d\u7f6e\u683c\u5f0f\uff0c\u5bf9\u4e8e Python \u7684\u5de5\u5177\u548c\u751f\u6001\u7cfb\u7edf\u5c24\u5176\u91cd\u8981\uff0c\u56e0\u4e3a\u5b83\u7528\u4e8e pyproject.toml \u914d\u7f6e\u6587\u4ef6\uff0c \u5230\u76ee\u524d\u4e3a\u6b62\uff0c\u4f60\u5fc5\u987b\u4f7f\u7528\u5916\u90e8\u5e93\u6765\u7ba1\u7406 TOML \u6587\u4ef6\uff0c\u4f46\u662f\u4ece Python 3.11 \u5f00\u59cb\uff0c\u5c06\u6709\u4e00\u4e2a\u540d\u4e3a tomllib \u7684\u5185\u7f6e\u5e93\uff0c\u5b83\u57fa\u4e8e toml \u5305\u3002<\/p>\n<p>\u6240\u4ee5\uff0c\u4e00\u65e6\u4f60\u5207\u6362\u5230 Python 3.11\uff0c\u4f60\u5e94\u8be5\u517b\u6210\u4f7f\u7528 import tomllib \u800c\u4e0d\u662f import tomli \u7684\u4e60\u60ef\u3002\u5c11\u4e86\u4e00\u79cd\u9700\u8981\u62c5\u5fc3\u7684\u4f9d\u8d56\uff01<\/p>\n<pre><code class=\"language-python\"># import tomli as tomllib\nimport tomllib\n\nwith open(&quot;pyproject.toml&quot;, &quot;rb&quot;) as f:\n    config = tomllib.load(f)\n    print(config)\n    # {&#039;project&#039;: {&#039;authors&#039;: [{&#039;email&#039;: &#039;contact@martinheinz.dev&#039;,\n    #                           &#039;name&#039;: &#039;Martin Heinz&#039;}],\n    #              &#039;dependencies&#039;: [&#039;flask&#039;, &#039;requests&#039;],\n    #              &#039;description&#039;: &#039;Example Package&#039;,\n    #              &#039;name&#039;: &#039;some-app&#039;,\n    #              &#039;version&#039;: &#039;0.1.0&#039;}}\n\ntoml_string = &quot;&quot;&quot;\n[project]\nname = &quot;another-app&quot;\ndescription = &quot;Example Package&quot;\nversion = &quot;0.1.1&quot;\n&quot;&quot;&quot;\n\nconfig = tomllib.loads(toml_string)\nprint(config)\n# {&#039;project&#039;: {&#039;name&#039;: &#039;another-app&#039;, &#039;description&#039;: &#039;Example Package&#039;, &#039;version&#039;: &#039;0.1.1&#039;}}<\/code><\/pre>\n<h2>Setuptools \u800c\u4e0d\u662f  distutils<\/h2>\n<p>\u6700\u540e\u4e00\u4e2a\u66f4\u50cf\u662f\u5f03\u7528\u901a\u77e5\uff1a<\/p>\n<p>\u7531\u4e8e Distutils \u5df2\u5f03\u7528\uff0c\u56e0\u6b64\u540c\u6837\u4e0d\u9f13\u52b1\u4f7f\u7528\u4efb\u4f55\u6765\u81ea distutils \u7684\u51fd\u6570\u6216\u5bf9\u8c61\uff0cSetuptools \u65e8\u5728\u66ff\u6362\u6216\u5f03\u7528\u6240\u6709\u6b64\u7c7b\u7528\u9014\u3002<\/p>\n<p>\u662f\u65f6\u5019\u544a\u522b distutils \u5305\u5e76\u5207\u6362\u5230 setuptools \u4e86\uff0csetuptools \u6587\u6863\u63d0\u4f9b\u4e86\u6709\u5173\u5982\u4f55\u66ff\u6362 distutils \u7528\u6cd5\u7684\u6307\u5bfc\uff0c \u9664\u6b64\u4e4b\u5916\uff0cPEP 632 \u8fd8\u4e3a setuptools \u672a\u6db5\u76d6\u7684\u90e8\u5206 distutils \u63d0\u4f9b\u8fc1\u79fb\u5efa\u8bae\u3002<\/p>\n<h2>\u603b\u7ed3<\/h2>\n<p>\u6bcf\u4e2a\u65b0\u7684 Python \u7248\u672c\u90fd\u4f1a\u5e26\u6765\u65b0\u7684\u7279\u6027\uff0c\u56e0\u6b64\u6211\u5efa\u8bae\u4f60\u67e5\u770b Python \u53d1\u884c\u8bf4\u660e\u4e2d\u7684\u201c\u65b0\u6a21\u5757\u201d\u3001\u201c\u4e0d\u63a8\u8350\u4f7f\u7528\u7684\u6a21\u5757\u201d\u548c\u201c\u5df2\u5220\u9664\u7684\u6a21\u5757\u201d\u90e8\u5206\uff0c\u8fd9\u662f\u4e86\u89e3 Python \u6807\u51c6\u91cd\u5927\u53d8\u5316\u7684\u597d\u65b9\u6cd5 \uff0c \u901a\u8fc7\u8fd9\u79cd\u65b9\u5f0f\uff0c\u4f60\u53ef\u4ee5\u4e0d\u65ad\u5730\u5c06\u65b0\u529f\u80fd\u548c\u6700\u4f73\u5b9e\u8df5\u6574\u5408\u5230\u4f60\u7684\u9879\u76ee\u4e2d\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u968f\u7740\u6bcf\u4e2a Python \u7248\u672c\u7684\u53d1\u5e03\uff0c\u90fd\u4f1a\u6dfb\u52a0\u65b0\u6a21\u5757\uff0c\u5e76\u5f15\u5165\u65b0\u7684\u66f4\u597d\u7684\u505a\u4e8b\u65b9\u5f0f\uff0c\u867d\u7136\u6211\u4eec\u90fd\u4e60\u60ef\u4e86\u4f7f\u7528\u597d\u7684\u65e7 Python \u5e93\u548c\u67d0\u4e9b\u505a\u4e8b\u65b9\u5f0f   \u2026 &#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0},"categories":[21],"tags":[],"_links":{"self":[{"href":"\/index.php?rest_route=\/wp\/v2\/posts\/9161"}],"collection":[{"href":"\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=9161"}],"version-history":[{"count":1,"href":"\/index.php?rest_route=\/wp\/v2\/posts\/9161\/revisions"}],"predecessor-version":[{"id":9162,"href":"\/index.php?rest_route=\/wp\/v2\/posts\/9161\/revisions\/9162"}],"wp:attachment":[{"href":"\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=9161"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=9161"},{"taxonomy":"post_tag","embeddable":true,"href":"\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=9161"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}