{"id":108,"date":"2026-08-06T00:30:24","date_gmt":"2026-08-05T16:30:24","guid":{"rendered":"https:\/\/ltrainyard.icu\/?p=108"},"modified":"2026-08-06T00:45:35","modified_gmt":"2026-08-05T16:45:35","slug":"day-21-%e9%98%b6%e6%ae%b5%e4%b8%89%e9%a1%b9%e7%9b%ae%ef%bc%9a%e5%91%bd%e4%bb%a4%e8%a1%8c%e8%ae%b0%e8%b4%a6%e6%9c%ac","status":"publish","type":"post","link":"https:\/\/ltrainyard.icu\/index.php\/2026\/08\/06\/day-21-%e9%98%b6%e6%ae%b5%e4%b8%89%e9%a1%b9%e7%9b%ae%ef%bc%9a%e5%91%bd%e4%bb%a4%e8%a1%8c%e8%ae%b0%e8%b4%a6%e6%9c%ac\/","title":{"rendered":"| Day 21 | \u9636\u6bb5\u4e09\u9879\u76ee\uff1a\u547d\u4ee4\u884c\u8bb0\u8d26\u672c |"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\">1 \u9879\u76ee\u603b\u89c8 \u2014\u2014 \u547d\u4ee4\u884c\u8bb0\u8d26\u672c\uff08\u9636\u6bb5\u4e09\u6536\u5b98\uff09<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u662f\u4ec0\u4e48\uff1f\u4e3a\u4ec0\u4e48\u5b66\uff1f<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u4eca\u5929\u662f\u9636\u6bb5\u4e09\u6536\u5b98\u65e5\uff0c<strong>\u6ca1\u6709\u65b0\u8bed\u6cd5<\/strong>\u2014\u2014\u628a\u6240\u6709\u77e5\u8bc6\u4e32\u8d77\u6765\u505a\u4e00\u4e2a<strong>\u547d\u4ee4\u884c\u8bb0\u8d26\u672c<\/strong>\u3002\u524d 20 \u5929\u5b66\u4e86\u8bed\u6cd5\u3001\u51fd\u6570\u3001\u6587\u4ef6\u3001\u9762\u5411\u5bf9\u8c61\u3001\u6807\u51c6\u5e93\uff0c\u4eca\u5929\u628a\u5b83\u7ec4\u88c5\u6210\u4e00\u4e2a\u300c\u771f\u6b63\u80fd\u7528\u7684\u300d\u547d\u4ee4\u884c\u8bb0\u8d26\u672c\uff1a\u8981\u6709\u6e05\u6670\u7684\u7c7b\u8bbe\u8ba1\u3001\u80fd\u4ea4\u4e92\u64cd\u4f5c\u3001\u6570\u636e\u5173\u673a\u4e0d\u4e22\u3002\u505a\u5b8c\u8fd9\u4e2a\u9879\u76ee\uff0c\u4f60\u5c31\u5177\u5907\u4e86\u300c\u72ec\u7acb\u628a\u4e00\u4e2a\u5c0f\u9700\u6c42\u505a\u6210\u7a0b\u5e8f\u300d\u7684\u80fd\u529b\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u9636\u6bb5\u77e5\u8bc6\u5730\u56fe<\/strong>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Day 15  \u7c7b\u4e0e\u5bf9\u8c61\uff08class\/\u5c5e\u6027\/\u65b9\u6cd5\/__init__\uff09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\nDay 16  \u7ee7\u627f\u4e0e\u591a\u6001\uff08\u5b50\u7c7b\u590d\u7528\/\u91cd\u5199\/\u9e2d\u5b50\u7c7b\u578b\uff09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\u2502\nDay 17  \u9b54\u6cd5\u65b9\u6cd5\uff08__str__\/__len__\/__eq__\/\u8fd0\u7b97\u7b26\u91cd\u8f7d\uff09 \u2500\u2510\u2502\u2502\nDay 18  \u8fed\u4ee3\u5668\u3001\u751f\u6210\u5668\u4e0e\u88c5\u9970\u5668\uff08\u60f0\u6027\u6c42\u503c\/@\u8bed\u6cd5\u7cd6\uff09 \u2500\u2500\u2500\u2500\u2510\u2502\u2502\u2502\nDay 19  \u5e38\u7528\u6807\u51c6\u5e93\uff08datetime\/collections\/itertools\/re\uff09\u2510\u2502\u2502\u2502\u2502\nDay 20  \u7b2c\u4e09\u65b9\u5e93\uff08pip\/venv\/requests\/beautifulsoup4\uff09 \u2500\u2500\u2510\u2502\u2502\u2502\u2502\u2502\n                                                    \u2514\u2500\u2534\u2534\u2534\u2534\u2534\u2534\u2500\u2500\u2192 \u9636\u6bb5\u9879\u76ee\uff1a\u547d\u4ee4\u884c\u8bb0\u8d26\u672c\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e00\u53e5\u8bdd\u4e32\u6cd5\uff1a<strong>\u7c7b\u628a\u6570\u636e\u548c\u51fd\u6570\u6253\u5305 \u2192 \u7ee7\u627f\u8ba9\u7c7b\u590d\u7528 \u2192 \u9b54\u6cd5\u65b9\u6cd5\u8ba9\u5bf9\u8c61\u300c\u50cf\u5185\u7f6e\u7c7b\u578b\u300d\u2192 \u751f\u6210\u5668\u88c5\u9970\u5668\u8ba9\u4ee3\u7801\u66f4\u4f18\u96c5 \u2192 \u6807\u51c6\u5e93\u63d0\u4f9b\u73b0\u6210\u5de5\u5177 \u2192 \u7b2c\u4e09\u65b9\u5e93\u6269\u5c55\u65e0\u9650\u80fd\u529b<\/strong>\u3002\u8bb0\u8d26\u672c\u5c31\u662f\u628a\u8fd9\u4e9b\u96f6\u4ef6\u6309\u987a\u5e8f\u7ec4\u88c5\u8d77\u6765\uff1a\u7c7b\u5f53\u9aa8\u67b6\u3001\u9b54\u6cd5\u65b9\u6cd5\u5f53\u300c\u6253\u5370\u95e8\u9762\u300d\u3001datetime \u8bb0\u65f6\u95f4\u3001json \u505a\u4fdd\u9669\u67dc\u3001\u5f02\u5e38\u5904\u7406\u5f53\u5b89\u5168\u6c14\u56ca\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6ce8\u610f\u4e8b\u9879\u603b\u7ed3<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1 <strong>\u9879\u76ee\u62c6\u89e3\u8868\uff08\u56db\u5927\u529f\u80fd \u2192 \u77e5\u8bc6\u70b9\uff09<\/strong>\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u529f\u80fd<\/th><th>\u7528\u5230\u7684\u77e5\u8bc6\u70b9<\/th><th>\u5177\u4f53\u5199\u6cd5<\/th><th>\u6765\u81ea\u54ea\u4e00\u5929<\/th><\/tr><\/thead><tbody><tr><td>\u6dfb\u52a0\u6536\u652f<\/td><td>\u7c7b\u4e0e\u5bf9\u8c61\u3001\u9b54\u6cd5\u65b9\u6cd5\u3001datetime\u3001\u5f02\u5e38\u5904\u7406<\/td><td><code>Record(rtype, category, amount, note)<\/code>\u3001<code>datetime.now()<\/code> \u6253\u65f6\u95f4\u6233\u3001<code>try\/except ValueError<\/code> \u62e6\u975e\u6cd5\u91d1\u989d<\/td><td>Day 15\/17\/19\/13<\/td><\/tr><tr><td>\u67e5\u770b\u6d41\u6c34<\/td><td>\u7c7b\u4e0e\u5bf9\u8c61\u3001\u9b54\u6cd5\u65b9\u6cd5<\/td><td><code>for r in book.records: print(r)<\/code> \u89e6\u53d1 <code>Record.__str__<\/code><\/td><td>Day 15\/17<\/td><\/tr><tr><td>\u7edf\u8ba1\u4f59\u989d<\/td><td>\u7c7b\u4e0e\u5bf9\u8c61\u3001\u751f\u6210\u5668\u8868\u8fbe\u5f0f<\/td><td><code>sum(r.amount for r in self.records if r.rtype == \"\u652f\u51fa\")<\/code><\/td><td>Day 15\/18<\/td><\/tr><tr><td>\u5206\u7c7b\u7edf\u8ba1<\/td><td>\u7c7b\u4e0e\u5bf9\u8c61\u3001\u5217\u8868\u63a8\u5bfc\u5f0f<\/td><td><code>[r for r in self.records if r.category == category]<\/code><\/td><td>Day 15\/6<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">2 <strong>\u6301\u4e45\u5316\u4e0e\u4ea4\u4e92 \u2192 \u77e5\u8bc6\u70b9<\/strong>\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u529f\u80fd<\/th><th>\u7528\u5230\u7684\u77e5\u8bc6\u70b9<\/th><th>\u5177\u4f53\u5199\u6cd5<\/th><th>\u6765\u81ea\u54ea\u4e00\u5929<\/th><\/tr><\/thead><tbody><tr><td>\u4fdd\u5b58\u6570\u636e<\/td><td>\u6807\u51c6\u5e93 json\u3001\u6587\u4ef6\u8bfb\u5199<\/td><td><code>json.dump(data, f, ensure_ascii=False, indent=2)<\/code><\/td><td>Day 19\/12\/11<\/td><\/tr><tr><td>\u52a0\u8f7d\u6570\u636e<\/td><td>\u6587\u4ef6\u5224\u65ad\u3001json\u3001\u5f02\u5e38\u5904\u7406<\/td><td><code>os.path.exists<\/code> + <code>json.load<\/code> + <code>except (json.JSONDecodeError, OSError)<\/code><\/td><td>Day 10\/12\/13<\/td><\/tr><tr><td>\u5e8f\u5217\u5316\u8f6c\u6362<\/td><td>\u9b54\u6cd5\u65b9\u6cd5\u3001\u7c7b\u65b9\u6cd5<\/td><td><code>Record.to_dict()<\/code>\uff08\u8f6c\u5b57\u5178\uff09\u3001<code>Record.from_dict()<\/code>\uff08@classmethod \u8f6c\u56de\u5bf9\u8c61\uff09<\/td><td>Day 17\/15<\/td><\/tr><tr><td>\u4e3b\u83dc\u5355<\/td><td>while \u5faa\u73af\u3001\u6761\u4ef6\u5224\u65ad<\/td><td><code>while True:<\/code> + <code>if\/elif<\/code> + <code>break<\/code><\/td><td>Day 4\/5<\/td><\/tr><tr><td>\u5bfc\u51fa CSV<\/td><td>\u6807\u51c6\u5e93 csv\u3001\u7f16\u7801<\/td><td><code>csv.DictWriter<\/code> + <code>encoding=\"utf-8-sig\"<\/code><\/td><td>Day 19\/12<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6613\u9519\u70b9<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u9519\u8bef\u5199\u6cd5\uff1a\u4e00\u53e3\u6c14\u5199\u5b8c 150 \u884c\u4ee3\u7801\u518d\u8fd0\u884c\uff08\u300c\u618b\u5927\u62db\u300d\uff09 \u2192 \u95ee\u9898\uff1a\u4e00\u8fd0\u884c\u5168\u662f\u9519\uff0c\u4e0d\u77e5\u9053\u4ece\u54ea\u6539\u8d77 \u2192 \u6b63\u786e\u5199\u6cd5\uff1a\u4e09\u6b65\u8d70\uff08\u9aa8\u67b6 \u2192 \u586b\u7a7a\u8179 \u2192 \u52a0\u6301\u4e45\u5316\u9632\u62a4\uff09\uff0c\u6bcf\u6b65\u90fd\u80fd\u8fd0\u884c\u9a8c\u8bc1\u3002<\/li>\n\n\n\n<li>\u9519\u8bef\u5199\u6cd5\uff1a\u9879\u76ee\u505a\u4e0d\u51fa\u6765\u5c31\u6000\u7591\u662f\u4eca\u5929\u7684\u95ee\u9898 \u2192 \u95ee\u9898\uff1a\u5f80\u5f80\u662f\u524d\u9762\u67d0\u5929\u57fa\u7840\u6ca1\u6253\u7262 \u2192 \u6b63\u786e\u5199\u6cd5\uff1a\u5bf9\u7167\u62c6\u89e3\u8868\u81ea\u67e5\u300c\u8fd9\u4e00\u6b65\u7528\u5230\u4e86\u54ea\u4e2a\u77e5\u8bc6\u70b9\u300d\uff0c\u56de\u53bb\u7ffb\u90a3\u4e00\u5929\u7684\u603b\u7ed3\u3002<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u8bb0\u5fc6\u53e3\u8bc0<\/strong>\uff1a\u7c7b\u5f53\u9aa8\u67b6\uff0c\u9b54\u6cd5\u65b9\u6cd5\u5f53\u95e8\u9762\uff1bdatetime \u8bb0\u65f6\u95f4\uff0cjson \u505a\u4fdd\u9669\u67dc\uff1b\u62c6\u89e3\u8868\u5bf9\u53f7\u5165\u5ea7\uff0c\u5c0f\u6b65\u8fed\u4ee3\u4e0d\u618b\u5927\u62db\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2 \u9700\u6c42\u5206\u6790\u4e0e\u7c7b\u8bbe\u8ba1 \u2014\u2014 Record \u4e0e Book<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u662f\u4ec0\u4e48\uff1f\u4e3a\u4ec0\u4e48\u5b66\uff1f<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u5148\u60f3\u6e05\u695a\u8981\u4ec0\u4e48\u529f\u80fd\uff1a\u6dfb\u52a0\u6536\u5165\/\u652f\u51fa\u3001\u67e5\u770b\u5168\u90e8\u6d41\u6c34\u3001\u7edf\u8ba1\u4f59\u989d\u3001\u6309\u7c7b\u522b\u7b5b\u9009\u3001\u4fdd\u5b58\u6570\u636e\u3002\u7a0b\u5e8f\u91cc\u6709\u4e24\u4e2a\u5929\u7136\u7684\u6982\u5ff5\uff0c\u62c6\u6210\u4e24\u4e2a\u7c7b\uff1a<code>Record<\/code>\uff08<strong>\u4e00\u6761<\/strong>\u6536\u652f\u8bb0\u5f55\uff09\u548c <code>Book<\/code>\uff08<strong>\u6574\u4e2a<\/strong>\u8d26\u672c\uff09\u3002\u4e00\u4e2a\u7c7b\u7ba1\u300c\u4e2a\u4f53\u300d\uff0c\u4e00\u4e2a\u7c7b\u7ba1\u300c\u6574\u4f53\u300d\uff0c\u804c\u8d23\u6e05\u6670\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6ce8\u610f\u4e8b\u9879\u603b\u7ed3<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1 <strong>Record \u7c7b\u2014\u2014\u4e00\u6761\u6536\u652f\u8bb0\u5f55<\/strong>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Record:\n    \"\"\"\u4e00\u6761\u6536\u652f\u8bb0\u5f55\"\"\"\n\n    def __init__(self, rtype, category, amount, note=\"\", date=None):\n        if rtype not in (\"\u6536\u5165\", \"\u652f\u51fa\"):\n            raise ValueError(\"\u7c7b\u578b\u53ea\u80fd\u662f \u6536\u5165 \u6216 \u652f\u51fa\")\n        self.rtype = rtype            # \u6536\u5165 \/ \u652f\u51fa\n        self.category = category      # \u9910\u996e\u3001\u4ea4\u901a\u3001\u5de5\u8d44\u2026\u2026\n        self.amount = float(amount)   # \u91d1\u989d\n        self.note = note              # \u5907\u6ce8\n        self.date = date or \"2026-08-03 09:00:00\"\n\n    def __str__(self):\n        symbol = \"+\" if self.rtype == \"\u6536\u5165\" else \"-\"\n        return f\"&#91;{self.date}] {self.rtype} {self.category} {symbol}{self.amount:.2f} {self.note}\"\n\n\nr = Record(\"\u652f\u51fa\", \"\u9910\u996e\", 25.5, \"\u5348\u996d\")\nprint(r)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u8fd0\u884c\u7ed3\u679c\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;2026-08-03 09:00:00] \u652f\u51fa \u9910\u996e -25.50 \u5348\u996d\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>__init__<\/code> \u91cc\u5148\u6821\u9a8c\u7c7b\u578b\uff08\u975e\u6cd5\u76f4\u63a5 <code>raise ValueError<\/code>\uff09\uff1b<code>__str__<\/code> \u51b3\u5b9a\u6253\u5370\u683c\u5f0f\uff0c<code>f\"{self.amount:.2f}\"<\/code> \u91d1\u989d\u4e24\u4f4d\u5c0f\u6570\uff0c<code>symbol<\/code> \u7528\u6761\u4ef6\u8868\u8fbe\u5f0f\u51b3\u5b9a <code>+<\/code> \u8fd8\u662f <code>-<\/code>\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">2 <strong>Book \u7c7b\u2014\u2014\u6dfb\u52a0\u3001\u7edf\u8ba1\u3001\u7b5b\u9009<\/strong>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Book:\n    def __init__(self):\n        self.records = &#91;]\n\n    def add_record(self, record):\n        self.records.append(record)\n\n    def balance(self):\n        \"\"\"\u6536\u5165\u52a0\u8d77\u6765\u51cf\u652f\u51fa\uff0c\u5f97\u5230\u4f59\u989d\"\"\"\n        total = 0.0\n        for r in self.records:\n            if r.rtype == \"\u6536\u5165\":\n                total += r.amount\n            else:\n                total -= r.amount\n        return total\n\n    def filter_by_category(self, category):\n        return &#91;r for r in self.records if r.category == category]\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>balance()<\/code> \u904d\u5386\u6240\u6709\u8bb0\u5f55\uff0c\u6536\u5165\u52a0\u3001\u652f\u51fa\u51cf\uff1b<code>filter_by_category<\/code> \u7528\u5217\u8868\u63a8\u5bfc\u5f0f\u7b5b\u51fa\u540c\u7c7b\u8bb0\u5f55\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6613\u9519\u70b9<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u9519\u8bef\u5199\u6cd5\uff1a\u4e00\u4e2a\u7c7b\u88c5\u6240\u6709\u4e1c\u897f\uff08\u4e00\u6761\u8bb0\u5f55\u548c\u6574\u4e2a\u8d26\u672c\u6df7\u5728\u4e00\u4e2a\u7c7b\u91cc\uff09 \u2192 \u95ee\u9898\uff1a\u804c\u8d23\u6df7\u4e71\uff0c\u6539\u4e00\u4e2a\u5730\u65b9\u5f71\u54cd\u5168\u5c40 \u2192 \u6b63\u786e\u5199\u6cd5\uff1a\u62c6\u6210 <code>Record<\/code>\uff08\u4e2a\u4f53\uff09\u548c <code>Book<\/code>\uff08\u6574\u4f53\uff09\uff0c\u5404\u7ba1\u5404\u7684\u3002<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u8bb0\u5fc6\u53e3\u8bc0<\/strong>\uff1a\u4e2a\u4f53 Record\uff0c\u6574\u4f53 Book\uff0c\u4e00\u4e2a\u7ba1\u4e00\u6761\u3001\u4e00\u4e2a\u7ba1\u5168\u672c\uff1b\u5b57\u6bb5\u6821\u9a8c\u653e\u6784\u9020\uff0c\u6253\u5370\u4ea4\u7ed9 __str__\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3 \u9b54\u6cd5\u65b9\u6cd5\u4e0e\u751f\u6210\u5668 \u2014\u2014 \u5bf9\u8c61\u7684\u300c\u95e8\u9762\u300d\u548c\u300c\u7edf\u8ba1\u300d<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u662f\u4ec0\u4e48\uff1f\u4e3a\u4ec0\u4e48\u5b66\uff1f<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>__str__<\/code> \u51b3\u5b9a\u300c\u6253\u5370\u4e00\u6761\u8bb0\u5f55\u300d\u957f\u4ec0\u4e48\u6837\u2014\u2014\u67e5\u770b\u6d41\u6c34\u65f6 <code>print(r)<\/code> \u76f4\u63a5\u8f93\u51fa\u53ef\u8bfb\u7684\u4e00\u884c\uff1b\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u8ba9\u300c\u7b5b\u9009 + \u6c42\u548c\u300d\u4e00\u884c\u641e\u5b9a\uff0c\u4e0d\u4ea7\u751f\u4e2d\u95f4\u5217\u8868\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6ce8\u610f\u4e8b\u9879\u603b\u7ed3<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1 <strong><strong>str<\/strong> \u8ba9\u300c\u6253\u5370\u4e00\u6761\u8bb0\u5f55\u300d\u4e00\u884c\u641e\u5b9a<\/strong>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Record:\n    def __init__(self, rtype, category, amount, note=\"\", date=\"2026-08-04 09:30:00\"):\n        self.rtype = rtype\n        self.category = category\n        self.amount = float(amount)\n        self.note = note\n        self.date = date\n\n    def __str__(self):\n        symbol = \"+\" if self.rtype == \"\u6536\u5165\" else \"-\"\n        return f\"&#91;{self.date}] {self.rtype} {self.category} {symbol}{self.amount:.2f} {self.note}\"\n\nr = Record(\"\u652f\u51fa\", \"\u9910\u996e\", 25.5, \"\u5348\u996d\")\nprint(r)   # \u89e6\u53d1 __str__\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u8fd0\u884c\u7ed3\u679c\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;2026-08-04 09:30:00] \u652f\u51fa \u9910\u996e -25.50 \u5348\u996d\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6ca1\u6709 <code>__str__<\/code>\uff0c\u6253\u5370\u5bf9\u8c61\u53ea\u4f1a\u770b\u5230 <code>&lt;__main__.Record object at 0x...&gt;<\/code>\uff0c\u5b8c\u5168\u6ca1\u6cd5\u770b<\/strong>\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">2 <strong>\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u7edf\u8ba1\u652f\u51fa\u603b\u989d\uff08\u60f0\u6027\u3001\u4e00\u884c\uff09<\/strong>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Book:\n    def __init__(self):\n        self.records = &#91;]\n\n    def expense_total(self):\n        return sum(r.amount for r in self.records if r.rtype == \"\u652f\u51fa\")\n\nbook = Book()\nbook.records = &#91;Record(\"\u652f\u51fa\", \"\u9910\u996e\", 25.5), Record(\"\u6536\u5165\", \"\u5de5\u8d44\", 8000)]\nprint(\"\u652f\u51fa\u603b\u989d:\", book.expense_total())\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u8fd0\u884c\u7ed3\u679c\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u652f\u51fa\u603b\u989d: 25.5\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>(r.amount for r in self.records if r.rtype == \"\u652f\u51fa\")<\/code> \u662f\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u2014\u2014<strong>\u8fb9\u904d\u5386\u8fb9\u8fc7\u6ee4\uff0c\u4e0d\u4ea7\u751f\u4e2d\u95f4\u5217\u8868<\/strong>\uff1b<code>sum()<\/code> \u6d88\u8d39\u5b83\u7b97\u51fa\u603b\u548c\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">3 <strong>datetime \u81ea\u52a8\u6253\u65f6\u95f4\u6233<\/strong>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from datetime import datetime\n\nclass Record:\n    def __init__(self, rtype, category, amount, note=\"\"):\n        self.rtype = rtype\n        self.category = category\n        self.amount = float(amount)\n        self.note = note\n        self.date = datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>datetime.now()<\/code> \u83b7\u53d6\u5f53\u524d\u65f6\u523b\uff0c<code>strftime(\"%Y-%m-%d %H:%M:%S\")<\/code> \u683c\u5f0f\u5316\u6210\u5b57\u7b26\u4e32\u5b58\u8fdb <code>self.date<\/code>\u2014\u2014<strong>\u6bcf\u6761\u8bb0\u5f55\u81ea\u52a8\u76d6\u4e0a\u65f6\u95f4\u6233\uff0c\u4e0d\u7528\u624b\u52a8\u8f93\u5165\u65f6\u95f4<\/strong>\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6613\u9519\u70b9<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u9519\u8bef\u5199\u6cd5\uff1a\u5fd8\u4e86\u5b9e\u73b0 <code>__str__<\/code> \u76f4\u63a5 <code>print(r)<\/code> \u2192 \u95ee\u9898\uff1a\u8f93\u51fa\u5185\u5b58\u5730\u5740\uff0c\u5b8c\u5168\u6ca1\u6cd5\u770b \u2192 \u6b63\u786e\u5199\u6cd5\uff1a\u4efb\u4f55\u81ea\u5b9a\u4e49\u7c7b\u90fd\u5b9e\u73b0 <code>__str__<\/code>\u3002<\/li>\n\n\n\n<li>\u9519\u8bef\u5199\u6cd5\uff1a\u624b\u5199 <code>for<\/code> + <code>if<\/code> + \u7d2f\u52a0\u505a\u7edf\u8ba1 \u2192 \u95ee\u9898\uff1a\u4ee3\u7801\u957f\u4e14\u5bb9\u6613\u9519 \u2192 \u6b63\u786e\u5199\u6cd5\uff1a\u751f\u6210\u5668\u8868\u8fbe\u5f0f + <code>sum()<\/code> \u4e00\u884c\u641e\u5b9a\u3002<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u8bb0\u5fc6\u53e3\u8bc0<\/strong>\uff1a<strong>str<\/strong> \u5b9a\u95e8\u9762\uff0c\u6253\u5370\u53d8\u4eba\u8bdd\uff1b\u751f\u6210\u5668\u4e00\u884c\u7edf\u8ba1\uff0cdatetime \u81ea\u52a8\u6253\u6233\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4 \u6301\u4e45\u5316\u4e0e\u5e8f\u5217\u5316 \u2014\u2014 \u5bf9\u8c61 \u2194 \u5b57\u5178 \u2194 JSON<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u662f\u4ec0\u4e48\uff1f\u4e3a\u4ec0\u4e48\u5b66\uff1f<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u7a0b\u5e8f\u5173\u4e86\u6570\u636e\u5c31\u6ca1\u4e86\uff0c\u8fd9\u4e0d\u884c\u3002\u7528 <code>json<\/code> \u6a21\u5757\u628a\u8bb0\u5f55\u5217\u8868\u8f6c\u6210\u6587\u672c\u5b58\u8fdb\u6587\u4ef6\uff0c\u542f\u52a8\u65f6\u518d\u8bfb\u56de\u6765\u3002\u4f46 JSON \u53ea\u8ba4 dict\/list\/str\/num\uff0c<strong>\u4e0d\u8ba4\u5bf9\u8c61<\/strong>\u2014\u2014\u6240\u4ee5\u9700\u8981 <code>Record.to_dict()<\/code>\uff08\u5b58\u4e4b\u524d\u8f6c\u5b57\u5178\uff09\u548c <code>Record.from_dict()<\/code>\uff08\u8bfb\u51fa\u6765\u8f6c\u56de\u5bf9\u8c61\uff09\uff0c\u6253\u901a\u300c\u5bf9\u8c61 \u2194 \u5b57\u5178 \u2194 JSON\u300d\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6ce8\u610f\u4e8b\u9879\u603b\u7ed3<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1 <strong>\u4fdd\u5b58\u548c\u52a0\u8f7d\u7684\u57fa\u672c\u59ff\u52bf<\/strong>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import json\n\nrecords = &#91;\n    {\"rtype\": \"\u6536\u5165\", \"category\": \"\u5de5\u8d44\", \"amount\": 8000, \"note\": \"\u6708\u85aa\"},\n    {\"rtype\": \"\u652f\u51fa\", \"category\": \"\u9910\u996e\", \"amount\": 25.5, \"note\": \"\u5348\u996d\"},\n]\n\n# \u4fdd\u5b58\uff1aensure_ascii=False \u8ba9\u4e2d\u6587\u6b63\u5e38\u663e\u793a\uff0cindent=2 \u683c\u5f0f\u5316\nwith open(\"records.json\", \"w\", encoding=\"utf-8\") as f:\n    json.dump(records, f, ensure_ascii=False, indent=2)\n\n# \u52a0\u8f7d\nwith open(\"records.json\", \"r\", encoding=\"utf-8\") as f:\n    loaded = json.load(f)\n\nprint(\"\u8bb0\u5f55\u6570:\", len(loaded))\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">2 <strong>to_dict \/ from_dict \u914d\u5408\uff08@classmethod \u5de5\u5382\u65b9\u6cd5\uff09<\/strong>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import json\n\n\nclass Record:\n    def __init__(self, rtype, category, amount, note=\"\"):\n        self.rtype = rtype\n        self.category = category\n        self.amount = float(amount)\n        self.note = note\n\n    def to_dict(self):\n        return {\"rtype\": self.rtype, \"category\": self.category,\n                \"amount\": self.amount, \"note\": self.note}\n\n    @classmethod\n    def from_dict(cls, data):\n        return cls(data&#91;\"rtype\"], data&#91;\"category\"], data&#91;\"amount\"], data.get(\"note\", \"\"))\n\n\nrecords = &#91;Record(\"\u6536\u5165\", \"\u5de5\u8d44\", 8000)]\ndata = &#91;r.to_dict() for r in records]\nwith open(\"records.json\", \"w\", encoding=\"utf-8\") as f:\n    json.dump(data, f, ensure_ascii=False, indent=2)\n\nwith open(\"records.json\", \"r\", encoding=\"utf-8\") as f:\n    back = &#91;Record.from_dict(item) for item in json.load(f)]\n\nprint(back&#91;0].rtype, back&#91;0].category, back&#91;0].amount)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u8fd0\u884c\u7ed3\u679c\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u6536\u5165 \u5de5\u8d44 8000.0\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>to_dict()<\/code> \u628a\u5bf9\u8c61\u8f6c\u6210\u5b57\u5178\uff08\u5b58\u6587\u4ef6\u524d\u8c03\u7528\uff09\uff1b<code>from_dict()<\/code> \u628a\u5b57\u5178\u8f6c\u56de\u5bf9\u8c61\uff08\u52a0\u8f7d\u65f6\u8c03\u7528\uff09\u3002<code>@classmethod<\/code> \u8ba9 <code>from_dict<\/code> \u80fd<strong>\u4e0d\u521b\u5efa\u5b9e\u4f8b<\/strong>\u5c31\u901a\u8fc7\u7c7b\u8c03\u7528\uff08<code>Record.from_dict(data)<\/code>\uff09\uff0c\u8fd4\u56de\u7684\u662f <code>cls(...)<\/code> \u6784\u9020\u7684\u65b0\u5bf9\u8c61\u2014\u2014\u8fd9\u5c31\u662f Day 18 \u7684\u300c\u5de5\u5382\u65b9\u6cd5\u300d\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6613\u9519\u70b9<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u9519\u8bef\u5199\u6cd5\uff1a\u76f4\u63a5\u628a <code>Record<\/code> \u5bf9\u8c61\u4e22\u7ed9 <code>json.dump<\/code> \u2192 \u95ee\u9898\uff1a\u62a5 <code>TypeError: Object of type Record is not JSON serializable<\/code> \u2192 \u6b63\u786e\u5199\u6cd5\uff1a\u5148 <code>to_dict()<\/code> \u8f6c\u6210\u5b57\u5178\u518d\u5b58\u3002<\/li>\n\n\n\n<li>\u9519\u8bef\u5199\u6cd5\uff1a\u8bfb\u5199\u6587\u4ef6\u6ca1\u6307\u5b9a\u7f16\u7801 \u2192 \u95ee\u9898\uff1a\u4e2d\u6587\u4e71\u7801\u6216\u62a5 <code>UnicodeDecodeError<\/code> \u2192 \u6b63\u786e\u5199\u6cd5\uff1a\u8bfb\u5199\u90fd\u52a0 <code>encoding=\"utf-8\"<\/code>\u3002<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u8bb0\u5fc6\u53e3\u8bc0<\/strong>\uff1aJSON \u53ea\u8ba4\u5b57\u5178\uff0c\u5bf9\u8c61\u5148 to_dict\uff1b\u8bfb\u56de\u7528 from_dict\uff0c\u5de5\u5382\u65b9\u6cd5 @classmethod\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5 \u52a8\u624b\u5b9e\u8df5 \u2014\u2014 \u5b8c\u6574\u547d\u4ee4\u884c\u8bb0\u8d26\u672c<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u628a\u56db\u4e2a\u90e8\u5206\u7ec4\u5408\u6210\u5b8c\u6574\u7a0b\u5e8f\uff0c\u76f4\u63a5\u4fdd\u5b58\u4e3a <code>account_book.py<\/code> \u8fd0\u884c\u5373\u53ef\u3002\u529f\u80fd\u5305\u542b\uff1a\u6dfb\u52a0\u6536\u652f\u3001\u67e5\u770b\u5168\u90e8\u6d41\u6c34\u3001\u7edf\u8ba1\u4f59\u989d\u3001\u6309\u7c7b\u522b\u7b5b\u9009\u3001\u4fdd\u5b58\u5230 JSON\u3001\u5bfc\u51fa CSV\u3001\u9000\u51fa\u65f6\u81ea\u52a8\u4fdd\u5b58\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># account_book.py \u2014\u2014 \u547d\u4ee4\u884c\u8bb0\u8d26\u672c\nimport csv\nimport json\nimport os\nfrom datetime import datetime\n\nDATA_FILE = \"records.json\"\nCATEGORIES = &#91;\"\u9910\u996e\", \"\u4ea4\u901a\", \"\u8d2d\u7269\", \"\u5a31\u4e50\", \"\u5de5\u8d44\", \"\u5176\u4ed6\"]\n\n\nclass Record:\n    \"\"\"\u4e00\u6761\u6536\u652f\u8bb0\u5f55\"\"\"\n\n    def __init__(self, rtype, category, amount, note=\"\", date=None):\n        if rtype not in (\"\u6536\u5165\", \"\u652f\u51fa\"):\n            raise ValueError(\"\u7c7b\u578b\u53ea\u80fd\u662f \u6536\u5165 \u6216 \u652f\u51fa\")\n        self.rtype = rtype\n        self.category = category\n        self.amount = float(amount)\n        self.note = note\n        self.date = date or datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\n\n    def to_dict(self):\n        return {\n            \"rtype\": self.rtype,\n            \"category\": self.category,\n            \"amount\": self.amount,\n            \"note\": self.note,\n            \"date\": self.date,\n        }\n\n    @classmethod\n    def from_dict(cls, data):\n        return cls(\n            data&#91;\"rtype\"],\n            data&#91;\"category\"],\n            data&#91;\"amount\"],\n            data.get(\"note\", \"\"),\n            data.get(\"date\", \"\"),\n        )\n\n    def __str__(self):\n        symbol = \"+\" if self.rtype == \"\u6536\u5165\" else \"-\"\n        return f\"&#91;{self.date}] {self.rtype} {self.category} {symbol}{self.amount:.2f} {self.note}\"\n\n\nclass Book:\n    \"\"\"\u8d26\u672c\uff1a\u7ba1\u7406\u6240\u6709\u6536\u652f\u8bb0\u5f55\"\"\"\n\n    def __init__(self):\n        self.records = &#91;]\n\n    def add_record(self, record):\n        self.records.append(record)\n\n    def balance(self):\n        total = 0.0\n        for r in self.records:\n            if r.rtype == \"\u6536\u5165\":\n                total += r.amount\n            else:\n                total -= r.amount\n        return total\n\n    def filter_by_category(self, category):\n        return &#91;r for r in self.records if r.category == category]\n\n    def save_json(self, path=DATA_FILE):\n        data = &#91;r.to_dict() for r in self.records]\n        with open(path, \"w\", encoding=\"utf-8\") as f:\n            json.dump(data, f, ensure_ascii=False, indent=2)\n        print(f\"\u5df2\u4fdd\u5b58 {len(self.records)} \u6761\u8bb0\u5f55\u5230 {path}\")\n\n    def save_csv(self, path=\"records.csv\"):\n        with open(path, \"w\", encoding=\"utf-8-sig\", newline=\"\") as f:\n            writer = csv.DictWriter(\n                f, fieldnames=&#91;\"date\", \"rtype\", \"category\", \"amount\", \"note\"]\n            )\n            writer.writeheader()\n            for r in self.records:\n                writer.writerow({\n                    \"date\": r.date,\n                    \"rtype\": r.rtype,\n                    \"category\": r.category,\n                    \"amount\": r.amount,\n                    \"note\": r.note,\n                })\n        print(f\"\u5df2\u5bfc\u51fa {len(self.records)} \u6761\u8bb0\u5f55\u5230 {path}\")\n\n    def load_json(self, path=DATA_FILE):\n        if not os.path.exists(path):\n            print(\"\u6ca1\u6709\u627e\u5230\u5b58\u6863\u6587\u4ef6\uff0c\u4ece\u7a7a\u8d26\u672c\u5f00\u59cb\")\n            return\n        with open(path, \"r\", encoding=\"utf-8\") as f:\n            data = json.load(f)\n        self.records = &#91;Record.from_dict(item) for item in data]\n        print(f\"\u5df2\u52a0\u8f7d {len(self.records)} \u6761\u5386\u53f2\u8bb0\u5f55\")\n\n\ndef main():\n    book = Book()\n    book.load_json()\n\n    while True:\n        print(\"\\n===== \u547d\u4ee4\u884c\u8bb0\u8d26\u672c =====\")\n        print(\"1. \u6dfb\u52a0\u6536\u5165\")\n        print(\"2. \u6dfb\u52a0\u652f\u51fa\")\n        print(\"3. \u67e5\u770b\u5168\u90e8\u6d41\u6c34\")\n        print(\"4. \u67e5\u770b\u4f59\u989d\")\n        print(\"5. \u6309\u7c7b\u522b\u7b5b\u9009\")\n        print(\"6. \u4fdd\u5b58\u5230 JSON\")\n        print(\"7. \u5bfc\u51fa CSV\")\n        print(\"0. \u9000\u51fa\uff08\u81ea\u52a8\u4fdd\u5b58\uff09\")\n        choice = input(\"\u8bf7\u9009\u62e9\u64cd\u4f5c: \").strip()\n\n        if choice in (\"1\", \"2\"):\n            rtype = \"\u6536\u5165\" if choice == \"1\" else \"\u652f\u51fa\"\n            category = input(f\"\u7c7b\u522b({','.join(CATEGORIES)}): \").strip()\n            try:\n                amount = float(input(\"\u91d1\u989d: \").strip())\n            except ValueError:\n                print(\"\u91d1\u989d\u5fc5\u987b\u662f\u6570\u5b57\uff0c\u8bf7\u91cd\u65b0\u64cd\u4f5c\")\n                continue\n            note = input(\"\u5907\u6ce8(\u53ef\u7559\u7a7a): \").strip()\n            book.add_record(Record(rtype, category, amount, note))\n            print(\"\u6dfb\u52a0\u6210\u529f\")\n\n        elif choice == \"3\":\n            if not book.records:\n                print(\"\u6682\u65e0\u8bb0\u5f55\")\n            else:\n                for r in book.records:\n                    print(r)\n\n        elif choice == \"4\":\n            print(f\"\u5f53\u524d\u4f59\u989d: {book.balance():.2f}\")\n\n        elif choice == \"5\":\n            category = input(f\"\u8f93\u5165\u7c7b\u522b({','.join(CATEGORIES)}): \").strip()\n            found = book.filter_by_category(category)\n            if not found:\n                print(\"\u8be5\u7c7b\u522b\u6682\u65e0\u8bb0\u5f55\")\n            else:\n                for r in found:\n                    print(r)\n\n        elif choice == \"6\":\n            book.save_json()\n\n        elif choice == \"7\":\n            book.save_csv()\n\n        elif choice == \"0\":\n            book.save_json()\n            print(\"\u518d\u89c1\uff0c\u6b22\u8fce\u4e0b\u6b21\u4f7f\u7528\")\n            break\n\n        else:\n            print(\"\u65e0\u6548\u9009\u62e9\uff0c\u8bf7\u91cd\u8bd5\")\n\n\nif __name__ == \"__main__\":\n    main()\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u8fd0\u884c\u4e00\u6b21\u5b8c\u6574\u6d41\u7a0b\uff08\u7b2c\u4e00\u6b21\u8fd0\u884c\uff09\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u6ca1\u6709\u627e\u5230\u5b58\u6863\u6587\u4ef6\uff0c\u4ece\u7a7a\u8d26\u672c\u5f00\u59cb\n\n===== \u547d\u4ee4\u884c\u8bb0\u8d26\u672c =====\n1. \u6dfb\u52a0\u6536\u5165\n2. \u6dfb\u52a0\u652f\u51fa\n3. \u67e5\u770b\u5168\u90e8\u6d41\u6c34\n4. \u67e5\u770b\u4f59\u989d\n5. \u6309\u7c7b\u522b\u7b5b\u9009\n6. \u4fdd\u5b58\u5230 JSON\n7. \u5bfc\u51fa CSV\n0. \u9000\u51fa\uff08\u81ea\u52a8\u4fdd\u5b58\uff09\n\u8bf7\u9009\u62e9\u64cd\u4f5c: 1\n\u7c7b\u522b(\u9910\u996e,\u4ea4\u901a,\u8d2d\u7269,\u5a31\u4e50,\u5de5\u8d44,\u5176\u4ed6): \u5de5\u8d44\n\u91d1\u989d: 8000\n\u5907\u6ce8(\u53ef\u7559\u7a7a): 8\u6708\u5de5\u8d44\n\u6dfb\u52a0\u6210\u529f\n\n\u8bf7\u9009\u62e9\u64cd\u4f5c: 3\n&#91;2026-08-03 15:30:00] \u6536\u5165 \u5de5\u8d44 +8000.00 8\u6708\u5de5\u8d44\n&#91;2026-08-03 15:32:00] \u652f\u51fa \u9910\u996e -25.50 \u5348\u996d\n\n\u8bf7\u9009\u62e9\u64cd\u4f5c: 4\n\u5f53\u524d\u4f59\u989d: 7974.50\n\n\u8bf7\u9009\u62e9\u64cd\u4f5c: 0\n\u5df2\u4fdd\u5b58 2 \u6761\u8bb0\u5f55\u5230 records.json\n\u518d\u89c1\uff0c\u6b22\u8fce\u4e0b\u6b21\u4f7f\u7528\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u518d\u6b21\u8fd0\u884c\u7a0b\u5e8f\u4f1a\u81ea\u52a8\u52a0\u8f7d <code>records.json<\/code>\uff0c\u5386\u53f2\u8bb0\u5f55\u90fd\u5728\u3002CSV \u5bfc\u51fa\u540e\u53ef\u4ee5\u7528 Excel \u6253\u5f00\uff08<code>utf-8-sig<\/code> \u7f16\u7801\u4fdd\u8bc1 Excel \u4e2d\u6587\u4e0d\u4e71\u7801\uff09\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u5347\u7ea7\u6311\u6218<\/strong>\uff1a\u52a0\u300c\u5220\u9664\u67d0\u6761\u8bb0\u5f55\u300d\u529f\u80fd\uff08\u7528\u5e8f\u53f7\u5220\uff09\uff1b\u52a0\u300c\u6309\u6708\u7edf\u8ba1\u300d\u529f\u80fd\uff08\u628a <code>Record.date<\/code> \u524d 7 \u4f4d <code>2026-08<\/code> \u4f5c\u4e3a\u6708\u4efd\u5206\u7ec4\u7edf\u8ba1\uff09\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">6 \u5f00\u53d1\u6d41\u7a0b \u2014\u2014 \u4e09\u6b65\u642d\u8d77\u8bb0\u8d26\u672c<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u662f\u4ec0\u4e48\uff1f\u4e3a\u4ec0\u4e48\u5b66\uff1f<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e0d\u8981\u4e00\u53e3\u6c14\u5199\u5b8c 150 \u884c\u4ee3\u7801\u2014\u2014\u65b0\u624b\u6700\u5e38\u89c1\u7684\u5931\u8d25\u65b9\u5f0f\u5c31\u662f\u300c\u618b\u5927\u62db\u300d\uff1a\u5199\u4e86\u51e0\u5341\u884c\u6ca1\u8fd0\u884c\u8fc7\u4e00\u6b21\uff0c\u4e00\u8fd0\u884c\u5168\u662f\u9519\uff0c\u6839\u672c\u4e0d\u77e5\u9053\u4ece\u54ea\u6539\u8d77\u3002\u6b63\u786e\u505a\u6cd5\u662f<strong>\u4e09\u6b65\u8d70\uff0c\u6bcf\u6b65\u90fd\u80fd\u8fd0\u884c\u3001\u90fd\u80fd\u9a8c\u8bc1<\/strong>\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6ce8\u610f\u4e8b\u9879\u603b\u7ed3<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1 <strong>\u7b2c 1 \u6b65\uff1a\u642d\u9aa8\u67b6\u2014\u2014\u5148\u8ba9\u83dc\u5355\u8dd1\u8d77\u6765<\/strong>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Record:\n    pass\n\nclass Book:\n    pass\n\ndef main():\n    while True:\n        choice = input(\"\u8bf7\u9009\u62e9\u64cd\u4f5c\uff080 \u9000\u51fa\uff09: \")\n        if choice == \"0\":\n            print(\"\u518d\u89c1\")\n            break\n        elif choice == \"1\":\n            print(\"\uff08\u529f\u80fd\u5f00\u53d1\u4e2d\uff09\")\n        else:\n            print(\"\u65e0\u6548\u9009\u62e9\uff0c\u8bf7\u91cd\u8bd5\")\n\nif __name__ == \"__main__\":\n    main()\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>pass<\/code> \u662f\u7a7a\u8bed\u53e5\uff0c\u8ba9\u7c7b\u80fd\u901a\u8fc7\u8bed\u6cd5\u68c0\u67e5\u3002<strong>\u8fd9\u4e00\u6b65\u7684\u610f\u4e49\uff1a\u5148\u628a\u300c\u7a0b\u5e8f\u7684\u5f62\u72b6\u300d\u7acb\u8d77\u6765\uff0c\u9519\u8bef\u8303\u56f4\u6700\u5c0f<\/strong>\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">2 <strong>\u7b2c 2 \u6b65\uff1a\u586b\u7a7a\u8179\u2014\u2014\u5148\u505a\u300c\u6dfb\u52a0\u300d\u548c\u300c\u67e5\u770b\u300d<\/strong>\uff1a\u628a <code>Record<\/code> \u548c <code>Book<\/code> \u7684 <code>pass<\/code> \u6362\u6210\u771f\u5b9e\u903b\u8f91\uff0c\u52a0\u4e0a\u6dfb\u52a0\u3001\u67e5\u770b\u3001\u4f59\u989d\u4e09\u4e2a\u529f\u80fd\uff0c\u8dd1\u4e00\u904d\uff1a\u80fd\u8bb0\u4e00\u7b14\u3001\u80fd\u770b\u6d41\u6c34\u3001\u4f59\u989d\u7b97\u5f97\u5bf9\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">3 <strong>\u7b2c 3 \u6b65\uff1a\u52a0\u6301\u4e45\u5316\u548c\u9632\u62a4\u2014\u2014\u4fdd\u5b58\/\u52a0\u8f7d + \u5f02\u5e38\u5904\u7406<\/strong>\uff1a\u6700\u540e\u8865\u4e0a <code>save_json<\/code> \/ <code>load_json<\/code> \/ <code>save_csv<\/code>\uff0c\u518d\u7ed9\u91d1\u989d\u8f93\u5165\u52a0\u4e0a <code>try \/ except ValueError<\/code>\u3002\u8fd9\u6b65\u662f\u300c\u9526\u4e0a\u6dfb\u82b1 + \u52a0\u56fa\u300d\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6613\u9519\u70b9<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u9519\u8bef\u5199\u6cd5\uff1a\u4e00\u6b21\u5199\u5b8c\u6240\u6709\u529f\u80fd\u518d\u8fd0\u884c \u2192 \u95ee\u9898\uff1a\u51fa\u9519\u8303\u56f4\u5927\uff0c\u96be\u4ee5\u5b9a\u4f4d \u2192 \u6b63\u786e\u5199\u6cd5\uff1a\u6bcf\u5b8c\u6210\u4e00\u6b65\u5c31\u8dd1\u4e00\u6b21\u3001\u9a8c\u8bc1\u4e00\u6b21\u2014\u2014\u51fa\u95ee\u9898\u8303\u56f4\u5c0f\u3001\u597d\u5b9a\u4f4d\u3002<\/li>\n\n\n\n<li>\u9519\u8bef\u5199\u6cd5\uff1a\u8df3\u8fc7\u9aa8\u67b6\u76f4\u63a5\u5199\u529f\u80fd \u2192 \u95ee\u9898\uff1a\u83dc\u5355\u903b\u8f91\u548c\u529f\u80fd\u903b\u8f91\u6df7\u5728\u4e00\u8d77 \u2192 \u6b63\u786e\u5199\u6cd5\uff1a\u5148\u8ba9\u83dc\u5355\u5faa\u73af\u8dd1\u901a\uff08\u7528 pass \u5360\u4f4d\uff09\uff0c\u518d\u9010\u4e2a\u586b\u7a7a\u3002<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u8bb0\u5fc6\u53e3\u8bc0<\/strong>\uff1a\u5148\u9aa8\u67b6\u540e\u586b\u7a7a\uff0c\u518d\u52a0\u56fa\uff1b\u6bcf\u6b65\u90fd\u8fd0\u884c\uff0c\u5c0f\u6b65\u5feb\u8fed\u4ee3\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u4eca\u65e5\u603b\u7ed3<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u9636\u6bb5\u77e5\u8bc6\u5730\u56fe\uff1a\u7c7b \u2192 \u7ee7\u627f\u591a\u6001 \u2192 \u9b54\u6cd5\u65b9\u6cd5 \u2192 \u751f\u6210\u5668\u88c5\u9970\u5668 \u2192 \u6807\u51c6\u5e93 \u2192 \u7b2c\u4e09\u65b9\u5e93\uff0c\u4e00\u73af\u6263\u4e00\u73af\n\u9700\u6c42\u5206\u6790\u5148\u884c\uff1a\u533a\u5206\u300c\u4e00\u6761\u8bb0\u5f55\u300d\uff08Record\uff09\u548c\u300c\u6574\u4e2a\u8d26\u672c\u300d\uff08Book\uff09\uff0c\u804c\u8d23\u6e05\u6670\n<code>__str__<\/code> \u5b9a\u6253\u5370\u95e8\u9762\uff1a<code>print(r)<\/code> \u76f4\u63a5\u8f93\u51fa\u53ef\u8bfb\u6d41\u6c34\uff1b\u6ca1\u6709\u5b83\u53ea\u80fd\u770b\u5230\u5185\u5b58\u5730\u5740\n\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u4e00\u884c\u7edf\u8ba1\uff1a<code>sum(r.amount for r in self.records if r.rtype == \"\u652f\u51fa\")<\/code>\n<code>datetime.now().strftime(...)<\/code> \u81ea\u52a8\u6253\u65f6\u95f4\u6233\uff0c\u4e0d\u7528\u624b\u52a8\u8f93\u5165\u65f6\u95f4\n\u6301\u4e45\u5316\u95ed\u73af\uff1a<code>Record.to_dict()<\/code>\uff08\u8f6c\u5b57\u5178\uff09\u2192 <code>json.dump<\/code> \u4fdd\u5b58 \u2192 <code>json.load<\/code> \u52a0\u8f7d \u2192 <code>Record.from_dict()<\/code>\uff08@classmethod \u8f6c\u56de\u5bf9\u8c61\uff09\n\u91d1\u989d\u8f93\u5165\u7528 <code>try\/except ValueError<\/code> \u62e6\u975e\u6cd5\u8f93\u5165\uff0c\u7a0b\u5e8f\u4e0d\u95ea\u9000\n\u5bfc\u51fa CSV \u7528 <code>utf-8-sig<\/code> \u7f16\u7801\uff0cExcel \u6253\u5f00\u4e2d\u6587\u4e0d\u4e71\u7801\n\u5f00\u53d1\u6d41\u7a0b\uff1a\u4e09\u6b65\u8d70\uff08\u9aa8\u67b6 \u2192 \u586b\u7a7a\u8179 \u2192 \u52a0\u6301\u4e45\u5316\u9632\u62a4\uff09\uff0c\u6bcf\u6b65\u90fd\u80fd\u8fd0\u884c\u9a8c\u8bc1\n\u72ec\u7acb\u5b8c\u6210\u547d\u4ee4\u884c\u8bb0\u8d26\u672c\uff0c\u6d4b\u8bd5\u975e\u6cd5\u8f93\u5165\u3001\u91cd\u542f\u52a0\u8f7d\u3001CSV \u5bfc\u51fa\u7b49\u573a\u666f<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u62a5\u9519<\/th><th>\u539f\u56e0<\/th><th>\u4fee\u590d<\/th><\/tr><\/thead><tbody><tr><td><code>ValueError: could not convert string to float: 'abc'<\/code><\/td><td>\u91d1\u989d\u8f93\u5165\u4e86\u975e\u6570\u5b57<\/td><td>\u7528 <code>try\/except<\/code> \u5305\u4f4f <code>float(input(...))<\/code>\uff0c\u8f93\u9519\u63d0\u793a\u91cd\u6765<\/td><\/tr><tr><td><code>json.decoder.JSONDecodeError<\/code><\/td><td>\u5b58\u6863\u6587\u4ef6\u88ab\u6539\u574f\u6216\u4e3a\u7a7a<\/td><td>\u5220\u9664 <code>records.json<\/code> \u91cd\u65b0\u5f00\u59cb\uff1b\u4fdd\u5b58\u65f6\u786e\u8ba4\u7528\u4e86 <code>json.dump<\/code><\/td><\/tr><tr><td>\u4e2d\u6587\u4e71\u7801<\/td><td>\u8bfb\u5199\u6587\u4ef6\u6ca1\u6307\u5b9a\u7f16\u7801<\/td><td>\u8bfb\u5199\u90fd\u52a0 <code>encoding=\"utf-8\"<\/code>\uff1b\u5bfc CSV \u7528 <code>utf-8-sig<\/code><\/td><\/tr><tr><td><code>TypeError: 'float' object is not subscriptable<\/code><\/td><td>\u628a\u91d1\u989d\u5f53\u5217\u8868\u7528\u4e86\uff08\u5982 <code>amount[0]<\/code>\uff09<\/td><td>\u91d1\u989d\u662f\u6570\u5b57\uff0c\u68c0\u67e5\u662f\u5426\u8bef\u7528\u4e0b\u6807<\/td><\/tr><tr><td>\u6570\u636e\u6ca1\u4fdd\u5b58<\/td><td>\u5fd8\u4e86\u8c03\u7528 <code>save_json<\/code>\uff0c\u6216\u9000\u51fa\u5206\u652f\u6ca1\u89e6\u53d1\u4fdd\u5b58<\/td><td>\u5728 <code>0<\/code> \u9000\u51fa\u5206\u652f\u91cc\u8c03\u7528 <code>book.save_json()<\/code><\/td><\/tr><tr><td><code>TypeError: Object of type Record is not JSON serializable<\/code><\/td><td>\u76f4\u63a5\u628a Record \u5bf9\u8c61\u4e22\u7ed9 <code>json.dump<\/code><\/td><td>\u5148 <code>to_dict()<\/code> \u8f6c\u6210\u5b57\u5178\u518d\u5b58<\/td><\/tr><\/tbody><\/table><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>1 \u9879\u76ee\u603b\u89c8 \u2014\u2014 \u547d\u4ee4\u884c\u8bb0\u8d26\u672c\uff08\u9636\u6bb5\u4e09\u6536\u5b98\uff09 \u662f\u4ec0\u4e48\uff1f\u4e3a\u4ec0\u4e48\u5b66\uff1f \u4eca\u5929\u662f\u9636\u6bb5\u4e09\u6536\u5b98\u65e5\uff0c\u6ca1\u6709\u65b0\u8bed\u6cd5\u2014\u2014\u628a\u6240\u6709\u77e5 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[16,9],"tags":[17],"class_list":["post-108","post","type-post","status-publish","format-standard","hentry","category-python","category-code-dev","tag-python-day"],"_links":{"self":[{"href":"https:\/\/ltrainyard.icu\/index.php\/wp-json\/wp\/v2\/posts\/108","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ltrainyard.icu\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ltrainyard.icu\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ltrainyard.icu\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ltrainyard.icu\/index.php\/wp-json\/wp\/v2\/comments?post=108"}],"version-history":[{"count":2,"href":"https:\/\/ltrainyard.icu\/index.php\/wp-json\/wp\/v2\/posts\/108\/revisions"}],"predecessor-version":[{"id":150,"href":"https:\/\/ltrainyard.icu\/index.php\/wp-json\/wp\/v2\/posts\/108\/revisions\/150"}],"wp:attachment":[{"href":"https:\/\/ltrainyard.icu\/index.php\/wp-json\/wp\/v2\/media?parent=108"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ltrainyard.icu\/index.php\/wp-json\/wp\/v2\/categories?post=108"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ltrainyard.icu\/index.php\/wp-json\/wp\/v2\/tags?post=108"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}