
\u6709\u4e2a\u6587\u4ef6\uff0c\u5305\u542b'\u2edd' 11997 \u548c\u98df\u662f\u76f8\u540c\u7684\u5b57\uff0c\u4f46\u662f\u662f\u4e0d\u540c\u7684\u7f16\u7801\uff0c
\n\u2edd (U+2EDD)\u548c \u98df (U+98DF)\u7684\u5173\u7cfb\u662f\uff1a\u5b83\u4eec\u662f\u540c\u4e00\u4e2a\u5b57\u7684\u4e0d\u540c\u89c6\u89c9\u8868\u73b0\u5f62\u5f0f\uff0c\u4f46 Unicode \u6307\u5b9a U+98DF \u4e3a\u6807\u51c6\u5f62\u5f0f\uff0cU+2EDD \u4e3a\u5176\u5f02\u4f53\u5f62\u5f0f\uff08\u7279\u522b\u662f\u4f5c\u4e3a\u90e8\u9996\u65f6\uff09\u3002
\n\u95ee\u4e86\u4e00\u4e0b AI \uff0c\u90fd\u662f\u8ba9\u679a\u4e3e\u505a\u4e00\u4e2a map \uff0c\u6709\u6ca1\u6709\u7edf\u4e00\u7684\u8f6c\u5316\u8fd9\u6837\u6c49\u5b57\u7684\u65b9\u6848\uff0cunicodedata.normalize \u4e0d\u884c\u3002
\n" }, { "author": { "url": "member/Leon6868", "name": "Leon6868", "avatar": "https://cdn.v2ex.com/avatar/14ed/48e6/438369_large.png?m=1748955348" }, "url": "t/1175519", "title": "\u6709\u54ea\u4e9b Python 3.14 Free-Threading \u591a\u7ebf\u7a0b\u6027\u80fd\u5206\u6790\u65b9\u6848\uff1f", "id": "t/1175519", "date_published": "2025-11-27T15:07:31+00:00", "content_html": "\u5982\u9898\uff0c\u6ca1\u627e\u5230\u5bf9\u4ee3\u7801\u5165\u4fb5\u5c0f\u3001\u80fd\u5904\u7406\u591a\u7ebf\u7a0b\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u8bf7\u95ee\u5927\u5bb6\u90fd\u662f\u600e\u4e48\u89e3\u51b3\u7684\u5462\uff1f
\n" }, { "author": { "url": "member/Daming798", "name": "Daming798", "avatar": "https://cdn.v2ex.com/avatar/b2b5/a321/577749_large.png?m=1735891240" }, "url": "t/1175211", "date_modified": "2025-11-26T08:00:12+00:00", "content_html": "\u6211\u4eec\u6b63\u9762\u5411\u4e2d\u5c0f\u4f01\u4e1a\u548c\u521d\u521b\u56e2\u961f\uff0c\u505a\u4e00\u6b3e\u4e13\u6ce8\u4e8e\u7528\u6237\u53cd\u9988\u7684\u7ba1\u7406\u5206\u6790\u5de5\u5177 \u2014\u2014 Feedalyze \u3002
\n\u5b83\u80fd\u591a\u6e20\u9053\u7edf\u4e00\u6536\u96c6\u3001\u9ad8\u6548\u5904\u7406\u3001\u53ef\u89c6\u5316\u5206\u6790\u7528\u6237\u53cd\u9988\uff0c\u5e2e\u52a9\u4e2d\u5c0f\u4f01\u4e1a\u6d1e\u5bdf\u7528\u6237\u9700\u6c42\uff0c\u52a0\u901f\u4ea7\u54c1\u8fed\u4ee3\u3002\u5730\u5740\uff1a https://feedalyze.com/
\nFeedalyze \u5bf9\u6807\u56fd\u5916\u7684 UserVoice + Dovetail \uff0c\u5e0c\u671b\u6210\u4e3a\u56fd\u5185\u4f01\u4e1a\u9996\u9009\u7684\u7528\u6237\u53cd\u9988\u7ba1\u7406\u5206\u6790\u5e73\u53f0\u3002
\n1 \u3001\u4ea7\u54c1\u5f00\u53d1\u8fed\u4ee3\u5e38\u9760\u731c\u6d4b\u6216\u7ecf\u9a8c\uff0c\u800c\u975e\u7528\u6237\u771f\u5b9e\u9700\u6c42\u3002\uff08\u5982\u679c\u53c2\u4e0e\u8fc7\u4e2d\u5c0f\u4f01\u4e1a\u4ea7\u54c1\u7814\u53d1\uff0c\u5c31\u80fd\u7406\u89e3\u8fd9\u70b9\uff09
\n2 \u3001\u5728\u6536\u96c6\u3001\u5904\u7406\u548c\u5206\u6790\u7528\u6237\u53cd\u9988\uff0c\u8c03\u67e5\u7528\u6237\u9700\u6c42\u65f6\uff0c\u4f01\u4e1a\u6210\u672c\u9ad8\u6602
\n3 \u3001\u96be\u4ee5\u53ca\u65f6\u6d1e\u5bdf\u7528\u6237\u9700\u6c42\uff0c\u5f71\u54cd\u4ea7\u54c1\u8fed\u4ee3\u901f\u5ea6\u548c\u51b3\u7b56\u6b63\u786e\u7387
\n4 \u3001\u7f3a\u4e4f\u53ef\u91cf\u5316\u7684\u6570\u636e\u652f\u6491\uff0c\u4ea7\u54c1\u65b9\u5411\u5bb9\u6613\u504f\u79bb\u5e02\u573a\u9700\u6c42\u7b49
\n\u5982\u679c\u4f60\u5bf9\u8fd9\u4e2a\u673a\u4f1a\u611f\u5174\u8da3\uff0c\u6b22\u8fce\u52a0\u5fae\u4fe1\u4e00\u8d77\u804a\u804a\uff0c\u5403\u4e2a\u996d\u3002\u6dfb\u52a0\u65f6\u8bf7\u5907\u6ce8\uff1a\u59d3\u540d + FastAPI
\n\u6211\u7684\u5fae\u4fe1\uff1aM-ing2020
\n", "date_published": "2025-11-26T07:59:46+00:00", "title": "\u62db\u52df\u4e00\u4f4d FastAPI \u5de5\u7a0b\u5e08\uff0c\u4f5c\u4e3a\u6280\u672f\u4f19\u4f34", "id": "t/1175211" }, { "author": { "url": "member/arnoldnuo", "name": "arnoldnuo", "avatar": "https://cdn.v2ex.com/avatar/e65a/afe1/219837_large.png?m=1759371311" }, "url": "t/1174867", "date_modified": "2025-11-26T00:17:16+00:00", "content_html": "chatgpt \u4e5f\u6ca1\u7ed9\u4e00\u4e2a\u5b9e\u7528\u7684\u65b9\u6848\uff0c\u4f60\u4eec\u90fd\u662f\u600e\u4e48\u7ba1\u7406\u81ea\u5df1\u7684 python \u73af\u5883\u7684\uff1f
\n", "date_published": "2025-11-25T03:18:14+00:00", "title": "\u4e3a\u4ec0\u4e48 Python \u7684\u5305\u7ba1\u7406\u8fd9\u4e48\u96be\u7528\uff0c\u6bd4 node \u7684 npm \u96be\u7528\u4e00\u4e07\u500d\uff0c\u6bcf\u6b21\u8fdb\u5165\u9879\u76ee\u90fd\u8981\u624b\u52a8\u6267\u884c\u4e00\u4e0b conda activate xxx\uff0c\u96be\u9053\u5c31\u6ca1\u6709\u9ed8\u8ba4\u7684 Python \u9879\u76ee\u7ea7\u522b\u7684\u4f9d\u8d56\u5417\uff1f", "id": "t/1174867" }, { "author": { "url": "member/wxmomomowx", "name": "wxmomomowx", "avatar": "https://cdn.v2ex.com/gravatar/0f52ae06c426eec78cf5043021132462?s=73&d=retro" }, "url": "t/1174561", "title": "\u7f51\u4e0a\u627e\u4e86\u4e2a\u6d41\u51fa\u7684 Python \u7a0b\u5e8f\uff0c\u60f3\u8fc7\u4e0b\u662f\u5426\u88ab\u6c61\u67d3\u4e86 \u90fd\u6709\u4ec0\u4e48\u63a8\u8350\u7684\u529e\u6cd5\u554a\uff1f", "id": "t/1174561", "date_published": "2025-11-23T16:51:47+00:00", "content_html": "\u7f51\u7ad9/\u7f51\u7edc\u7a0b\u5e8f\u6765\u7684\uff0c\u4f1a\u653e\u5c0f\u9e21\u8dd1\u8dd1\u770b\u3002\u76ee\u524d\u662f fastapi+tortoise orm \uff0c\u8003\u5bdf\u4e86\u51e0\u4e2a
\ndjango admin \u6709\u70b9\u91cd
\nfastapi-admin\uff1a \u6298\u817e\u5f97\u5f88\u9ebb\u70e6\uff0c
\nfastadmin: \u8fd9\u4e2a\u662f\u6700\u7b80\u5355\u7684\uff0c\u4f46\u662f\u529f\u80fd\u6709\u70b9\u7b80\u964b\uff0c\u5f88\u591a\u524d\u7aef\u7684\u529f\u80fd\u6ca1\u6709\u5b9e\u73b0\u3002
\n" }, { "author": { "url": "member/dylyft", "name": "dylyft", "avatar": "https://cdn.v2ex.com/gravatar/8975f667291303f787181c55b320a651?s=73&d=retro" }, "url": "t/1171662", "title": "\u5c0f\u767d\u6c42\u6559\u4e2a\u5faa\u73af\u5bfc\u5165\u7684\u95ee\u9898", "id": "t/1171662", "date_published": "2025-11-10T03:24:39+00:00", "content_html": "\u6700\u8fd1\u521a\u5f00\u59cb\u5b66 python \u548c fastapi, \u6309\u7167 fastapi \u6559\u7a0b\u5b66\u4e60\u65f6\u9047\u5230\u4e2a\u95ee\u9898, \u56e0\u4e3a\u4f7f\u7528 sqlmodel \u7684 relationship, \u5bfc\u81f4\u4e24\u4e2a\u6a21\u578b\u6587\u4ef6\u76f8\u4e92\u5bfc\u5165, \u7136\u540e\u62a5\u9519\u4e86, \u6839\u636e\u5b98\u65b9\u6587\u6863\u7684\u89e3\u51b3\u529e\u6cd5, \u4f7f\u7528 TYPE_CHECKING \u548c\u5b57\u7b26\u4e32\u7248\u672c\u7c7b\u578b\u540e\u6682\u65f6\u89e3\u51b3\u4e86\u62a5\u9519.
\n\u4f46\u662f\u5f53\u63a5\u53e3\u901a\u8fc7 response_model \u6307\u5b9a\u4e86\u6570\u636e\u6a21\u578b(\u975e\u8868\u6a21\u578b)\u4f5c\u4e3a\u8fd4\u56de\u7c7b\u578b\u65f6, \u53c8\u51fa\u73b0\u4e86\u62a5\u9519, \u62a5\u9519\u63d0\u793a\u5982\u4e0b:
`TypeAdapter[typing.Annotated[app.models.teams.TeamPublicWithUser, FieldInfo(annotation=TeamPublicWithUser, required=True)]]` is not fully defined; you should define `typing.Annotated[app.models.teams.TeamPublicWithUser, FieldInfo(annotation=TeamPublicWithUser, required=True)]` and all referenced types, then call `.rebuild()` on the instance.\n\n\u6c42\u5404\u4f4d\u5927\u4f6c\u5e2e\u5fd9\u770b\u770b, \u54ea\u91cc\u6709\u95ee\u9898.\npython \u7248\u672c\u7528\u7684\u662f 3.12, \u5177\u4f53\u4ee3\u7801\u5982\u4e0b
\nmodels/users.py
from typing import TYPE_CHECKING, Any, Optional\n\nfrom sqlmodel import Field, Relationship, SQLModel\n\nif TYPE_CHECKING:\n from .teams import Team, TeamPublic\n\n\nclass UserBase(SQLModel):\n username: str = Field(index=True, max_length=255, unique=True)\n email: str | NOne= Field(default=None, index=True, max_length=255)\n is_active: bool = True\n is_superuser: bool = False\n full_name: str | NOne= Field(default=None, max_length=255)\n team_id: int | NOne= Field(default=None, foreign_key=\"team.id\")\n\n\nclass User(UserBase, table=True):\n id: int | NOne= Field(default=None, primary_key=True)\n hashed_password: str\n team: Optional[\"Team\"] = Relationship(back_populates=\"members\")\n\n\nclass UserPublic(UserBase):\n id: int\n\n\nclass UserPublicWithTeam(UserPublic):\n team: Optional[\"TeamPublic\"] = None\n\nmodels/teams.py
\nfrom typing import TYPE_CHECKING, Any, List\n\nfrom sqlmodel import Field, Relationship, SQLModel\n\nif TYPE_CHECKING:\n from .users import User, UserPublic\n\n\nclass TeamBase(SQLModel):\n name: str = Field(max_length=255)\n\n\nclass Team(TeamBase, table=True):\n id: int | NOne= Field(default=None, primary_key=True)\n members: List[\"User\"] = Relationship(back_populates=\"team\")\n\n\nclass TeamPublic(TeamBase):\n id: int\n\n\nclass TeamPublicWithUser(TeamPublic):\n members: List[\"UserPublic\"] = []\n\nrouter/users.py
\n# \u7528\u6237\u76f8\u5173\u63a5\u53e3\nfrom sqlmodel import and_, select\n\nfrom app.api.deps import SessionDep\nfrom app.models.users import (\n User,\n UserPublicWithTeam,\n)\nfrom app.new_router import new_router\n\nrouter = new_router(prefix=\"/users\", tags=[\"\u7528\u6237\u7ba1\u7406\"])\n\n\n@router.get(\"/{id}\", summary=\"\u83b7\u53d6\u7528\u6237\u8be6\u60c5\", response_model=UserPublicWithTeam)\nasync def get_user_api(db: SessionDep, id: int):\n user = db.exec(select(User).where(and_(User.id == id, User.is_active))).first()\n return user\n\nrouter/teams.py
\n# \u56e2\u961f\u76f8\u5173\u63a5\u53e3\nfrom sqlmodel import select\n\nfrom app.api.deps import SessionDep\nfrom app.models.teams import (\n Team,\n TeamPublicWithUser,\n)\nfrom app.new_router import new_router\n\nrouter = new_router(prefix=\"/teams\", tags=[\"\u56e2\u961f\u7ba1\u7406\"])\n\n\n@router.get(\"/{id}\", summary=\"\u83b7\u53d6\u56e2\u961f\u8be6\u60c5\", response_model=TeamPublicWithUser)\nasync def get_team_api(db: SessionDep, id: int):\n team = db.exec(select(Team).where(Team.id == id)).first()\n return team\n\n" }, { "author": { "url": "member/enrolls", "name": "enrolls", "avatar": "https://cdn.v2ex.com/avatar/5e2c/35af/114646_large.png?m=1763529309" }, "url": "t/1171056", "title": "\u7528 Python \u5199\u4e86\u4e2a\u5f02\u6b65 MCP Filesystem\uff0c\u5c0f\u800c\u7b80\uff0c\u6b22\u8fce\u62cd\u7816", "id": "t/1171056", "date_published": "2025-11-06T11:48:53+00:00", "content_html": "\u4e3a\u4ec0\u4e48\u8fd8\u8981\u505a\u4e00\u4e2a MCP Filesystem \u7684 Python \u5b9e\u73b0\uff1f
\n\u76ee\u524d MCP \u751f\u6001\u91cc\uff0c\u5f88\u591a\u80fd\u529b\u662f Node.js \u5b9e\u73b0\u7684\uff0cPython \u8fd9\u8fb9\u8981\u4e48\u53ea\u662f\u5c01\u88c5\u4e00\u5c42\uff0c\u8981\u4e48\u504f\u540c\u6b65\u963b\u585e\u3002\u5bf9\u90a3\u79cd\u201c\u6211\u5c31\u60f3\u5199\u4e2a async \u5c0f\u5de5\u5177\u201d\u7684\u573a\u666f\uff0c\u5176\u5b9e\u4e0d\u592a\u53cb\u597d\uff1a
\n\u6240\u4ee5\u5728\u81ea\u5df1\u7684 MCP \u5de5\u5177\u91cc\uff0c\u57fa\u4e8e\u5b98\u65b9\u534f\u8bae\u641e\u4e86\u4e00\u4e2a\u300c\u7cbe\u7b80\u7248\u300d\u5b9e\u73b0\uff0c\u4e3b\u8981\u7279\u70b9\uff1a
\nasync\uff0c\u65b9\u4fbf\u76f4\u63a5\u63a5\u5230\u73b0\u6709\u7684 async Web \u6846\u67b6 / \u4efb\u52a1\u7cfb\u7edf \u53ef\u4ee5\u81ea\u884c TODO / \u4e8c\u6b21\u5f00\u53d1\u7684\u65b9\u5411\u5305\u62ec\uff1a
\nDATA_DIR \u505a\u76ee\u5f55\u6c99\u7bb1\uff0c\u9632\u6b62\u8d8a\u754c\u8bbf\u95ee\uff0c\u907f\u514d\u4e00\u4e0a\u6765\u5c31\u6478\u6574\u4e2a\u78c1\u76d8 Github \u9879\u76ee\u5730\u5740\uff1a
\n\n\u6280\u672f\u542b\u91cf\u4e0d\u591a\uff0c\u7eaf\u7cb9\u6709\u76f8\u540c\u9700\u6c42\u7684\u4eba\u53ef\u4ee5\u4e0d\u7528\u518d\u601d\u8003\u592a\u591a\uff0c\u76f4\u63a5\u7528\uff0c\u4e5f\u53ef\u4ee5\u5f53\u4f5c\u7ec4\u4ef6\u62fc\u63a5\u5230\u5176\u4ed6\u5730\u65b9\u3002
\n" }, { "author": { "url": "member/superhxl", "name": "superhxl", "avatar": "https://cdn.v2ex.com/avatar/9104/9ee3/437853_large.png?m=1652336459" }, "url": "t/1170555", "title": "Neovim \u7684\u4ee3\u7801\u68c0\u67e5\u3001\u8865\u5168\u95ee\u9898", "id": "t/1170555", "date_published": "2025-11-05T01:01:10+00:00", "content_html": "Neovim \u91c7\u7528 nvim-cmp + pyright \u8fdb\u884c Python \u4ee3\u7801\u68c0\u67e5\u3001\u8865\u5168\uff0c\u4f46\u662f\u5bf9\u4e8e\u590d\u6742\u7684\u4ee3\u7801\uff0c\u8b6c\u5982\u81ea\u5b9a\u4e49\u7c7b\uff0c\u7ee7\u627f\u81ea\u7236\u7c7b\u7684\u4e00\u4e9b\u5c5e\u6027\u3001\u65b9\u6cd5\u5c31\u68c0\u6d4b\u4e0d\u5230\uff0c\u63d0\u793a\u9519\u8bef\u3002\u5982\u56fe\uff1a\n
\n\u81ea\u5b9a\u4e49\u7c7b MoneyAgent \u4e2d\u6709\u7ee7\u627f\u81ea\u7236\u7c7b CellAgent \u7684\u5bf9\u8c61 cell \uff0ccell \u5177\u6709\u5c5e\u6027 neighborhood \uff0cpyright \u5b8c\u5168\u610f\u8bc6\u4e0d\u5230\u3002\n\u8bf7\u6559\uff1a\n1 \u3001\u662f\u4e0d\u662f\u6709\u8bbe\u7f6e\u65b9\u6cd5\u53ef\u4ee5\u6539\u8fdb\u3001\u63d0\u5347\n2 \u3001\u9664\u4e86 pyright \u6216\u8005 nvim-cmp \uff0c\u662f\u4e0d\u662f\u8fd8\u6709\u66f4\u597d\u7684\u8865\u5168\u5de5\u5177\uff1f\n\u8c22\u8c22\uff0c\u8bf7\u5404\u4f4d V \u53cb\u4e0d\u541d\u8d50\u6559\u3002
pip \u9ed8\u8ba4\u8fde\u63a5\u7684\u662f\u4f4d\u4e8e\u6d77\u5916\u7684 PyPI \u5b98\u65b9\u6e90\uff0c\u7f51\u7edc\u5ef6\u8fdf\u7684\u65f6\u5019\u4e0b\u8f7d\u901f\u5ea6\u975e\u5e38\u6162\u3002
\n\u6240\u4ee5\uff0c\u76f4\u63a5\u5199\u4e86\u4e00\u4e2a pip fast check pypi
\n\n\n\n
pip install -U pip-fc
\n\n\n
pip-fc\u6216\u8005python -m pip-fc
\u4f7f\u7528 pdm \u7684\u9879\u76ee\u4eca\u5929\u7a81\u7136\u6784\u5efa\u5931\u8d25\u4e86\uff0c\u53bb\u5b98\u65b9 issue \u641c\u4e86\u4e0b\uff0c\u53d1\u73b0\u662f\u56e0\u4e3a hishel \u5347\u7ea7 1.0.0 \u5bfc\u81f4\u4e0d\u517c\u5bb9\u3002
\n\u6211\u7684 Dockerfile \u89e3\u51b3\u65b9\u6848\u5982\u4e0b
\npip install --no-cache-dir -U \"pdm==2.25.9\" \"hishel<1.0.0\"
\nhttps://github.com/pdm-project/pdm/issues/3657
\nhttps://github.com/karpetrosyan/hishel
\n" }, { "author": { "url": "member/rev1si0n", "name": "rev1si0n", "avatar": "https://cdn.v2ex.com/gravatar/e1f3c758ad2fa84197b239ab19487e32?s=73&d=retro" }, "url": "t/1167751", "title": "\u5f00\u6e90\u4e00\u4e2a Python JA3 \u8bf7\u6c42\u5e93\u3002\u53ef\u4ee5\u81ea\u5b9a\u4e49 JA3 \u6307\u7eb9\u5e76\u4e14\u5185\u7f6e 1200 \u591a\u4e2a JA3 \u6307\u7eb9\u3002", "id": "t/1167751", "date_published": "2025-10-23T01:19:08+00:00", "content_html": "\u722c\u866b\u4e2d\u53ef\u80fd\u9047\u5230\u4f60\u4ec0\u4e48\u53c2\u6570\u90fd\u62fc\u5bf9\u4e86\u4f46\u662f\u8fd8\u662f\u6ca1\u6cd5\u8bf7\u6c42\u7684\u60c5\u51b5\uff0c\u6ca1\u9519\uff0c\u4f60\u53ef\u80fd\u662f\u9047\u5230\u4e86 JA3 \u6307\u7eb9\uff0c\u4ece TLS \u5c42\u9762\u5c31\u5df2\u7ecf\u628a\u4f60\u8bc6\u522b\u4e86\uff0c\u6240\u4ee5\u518d\u505a\u4ec0\u4e48\u4e5f\u662f\u65e0\u7528\uff0c\u653e\u5fc3\u4ed6\u80fd\u5e2e\u4f60\u3002\u867d\u7136\u53ea\u662f\u5957\u58f3\u4f46\u662f\u80fd\u8ba9 Python \u76f4\u63a5\u8c03\u7528\u4e5f\u662f\u5f88\u597d\u4e86\uff0c\u4f60\u4e5f\u53ef\u4ee5\u57fa\u4e8e\u6b64\u65b9\u6848\u5b9e\u73b0\u66f4\u9ad8\u7ea7\u7684\u8bf7\u6c42\u5e93\u3002
\nGithub: https://github.com/rev1si0n/ja3
\n" }, { "author": { "url": "member/ASLant", "name": "ASLant", "avatar": "https://cdn.v2ex.com/gravatar/0588b56ec2564818e84e17505a48a6d2?s=73&d=retro" }, "url": "t/1166979", "title": "Arm64 \u5b89\u88c5 PyQt5/6\uff0c\u53ea\u80fd\u9009 conda \u5417\uff1f", "id": "t/1166979", "date_published": "2025-10-20T05:32:02+00:00", "content_html": "\u516c\u53f8\u4e00\u76f4\u7528 jetson orin nano \u548c NX \u8bbe\u5907\u5f00\u53d1\u6848\u4f8b\uff0c\u4f46\u662f\u9700\u8981\u4f7f\u7528 Python + Qt \uff0c\u76ee\u524d\u4e00\u76f4\u91c7\u7528 miniconda3 \u6765\u5b89\u88c5 PyQt5 \u8fd9\u4e2a\u5e93\uff0c\u65e0\u6cd5\u4f7f\u7528 pip \u76f4\u63a5\u7f16\u8bd1\u5b89\u88c5\uff0c\u6211\u8ba4\u4e3a\u6027\u80fd\u662f\u5b8c\u5168\u591f\u7684\uff0c8G \u5185\u5b58\uff0c\u4f46\u662f\u7f16\u8bd1\u5b89\u88c5 Qt \u8fd8\u662f\u5931\u8d25\u3002\u4f46\u662f miniconda \u6709\u70b9\u81c3\u80bf\uff0c\u80fd\u7528\u662f\u80fd\u7528\uff0c\u4f46\u662f\u4e0d\u597d\u7528\uff0cX86 \u8bbe\u5907\u90fd\u6539\u6210\u4e86 uv \u7edf\u4e00\u7ba1\u7406\uff0c\u56e0\u4e3a\u5f00\u53d1\u7684\u6848\u4f8b\u6d89\u53ca\u5230\u73af\u5883\u91cd\u7f6e\u7b49\uff0cuv \u548c poetry \u8fd9\u79cd\u6bd4\u8f83\u597d\uff0c\u53ef\u4ee5 100%\u8fd8\u539f\u4f9d\u8d56\u3002conda \u5bfc\u51fa\u7684 yaml \u6709\u65f6\u5019\u4e5f\u662f\u4f1a\u62bd\u98ce\uff0c\u603b\u662f\u6f0f\u4e2a\u5305\u4e4b\u7c7b\u7684\u3002\u4f46\u662f\u53c8\u79bb\u4e0d\u5f00 PyQt \u3002\u6240\u4ee5 \u8fd8\u6709\u62db\u5417\uff1f apt \u5b89\u88c5\u7684\u5168\u5c40\uff0c\u597d\u50cf\u4e0d\u592a\u517c\u5bb9\u3002
\n\u5728 arm64 \u4e0a\u4f7f\u7528 pip \u5b89\u88c5\u7f16\u8bd1 PyQt \u5e93\uff0c100%\u5931\u8d25\uff0cpip \u4e5f\u6ca1\u6709 arm64 \u8bbe\u5907\u9884\u7f16\u8bd1\u597d\u7684 wheel.\nconda \u5728 arm64 \u8bbe\u5907\u63d0\u4f9b\u9884\u7f16\u8bd1\u597d\u7684 pyqt \u5e93\uff0cconda install \u662f\u53ef\u4ee5\u76f4\u63a5\u57fa\u4e8e\u5f53\u524d Python \u7248\u672c\u5b89\u88c5\u7684\uff0c\u4e0d\u9700\u8981\u7f16\u8bd1.
\n" }, { "author": { "url": "member/happytaoer", "name": "happytaoer", "avatar": "https://cdn.v2ex.com/gravatar/1c9e069b9bcb24dfb8a9c6172021187c?s=73&d=retro" }, "url": "t/1166906", "title": "Python \u722c\u866b\u5fae\u6846\u67b6 web-craft", "id": "t/1166906", "date_published": "2025-10-20T02:29:55+00:00", "content_html": "\u8fd9\u4e24\u5929\u6784\u601d\u4e86\u4e00\u4e2a\u722c\u866b\u6846\u67b6\uff0c\u5bf9\u5916\u63d0\u4f9b API \u521b\u5efa\u722c\u866b\u4efb\u52a1\uff0c\u7136\u540e\u5185\u90e8\u7684\u961f\u5217\u4f1a\u8fdb\u884c\u722c\u866b\u7684\u6d88\u8d39\u3002\u53ea\u9700\u8981\u5b9e\u73b0\u6570\u636e\u7684\u89e3\u6790\u63a5\u53e3\u5c31\u80fd\u5feb\u901f\u7f16\u5199\u722c\u866b\u3002\u975e\u5e38\u9002\u5408\u9700\u8981\u5229\u7528 AI \u5feb\u901f\u751f\u6210\u722c\u866b\u4ee3\u7801\u7684\u56e2\u961f\u3002\n
\u8fd9\u4e2a\u6846\u67b6\u5bf9\u5916\u63d0\u4f9b\u4e86 API \u63a5\u53e3\u6765\u521b\u5efa\uff0c\u975e\u5e38\u4fbf\u5229\u3002\u76ee\u524d\u7684\u8bbe\u8ba1\u601d\u8def\u5c31\u662f\u53ea\u9700\u8981\u5b9e\u73b0\u4e00\u4e2a parse \u63a5\u53e3\uff0c\u5c31\u884c\u4e86\uff0c\u65b9\u4fbf\u540e\u7eed AI \u7684\u4ecb\u5165\u3002
\n\u76ee\u524d\u8fd9\u662f\u4e00\u4e2a\u975e\u5e38\u7b80\u5355\u6e05\u6670\u7684\u9879\u76ee\uff0c\u5e0c\u671b\u548c\u611f\u5174\u8da3\u7684\u670b\u53cb\u5171\u5efa\u8fd9\u4e2a\u9879\u76ee\uff0c\u63d0\u5347\u5927\u5bb6\u7684\u6280\u672f\u5f71\u54cd\u529b\uff0c\u6216\u8bb8\u5bf9\u627e\u8fdc\u7a0b\u5de5\u4f5c\u4e5f\u662f\u6709\u5e2e\u52a9\u7684\u3002
\n\u9879\u76ee\u5730\u5740\uff1a\nhappytaoer/web-craft: A Python-based modular web scraping framework focused on efficient single URL crawling, supporting asynchronous processing, API services, and highly customizable spider modules.
\n" }, { "author": { "url": "member/EndlessSummer", "name": "EndlessSummer", "avatar": "https://cdn.v2ex.com/gravatar/cb94134a89f5f0731791f3f5af66e709?s=73&d=retro" }, "url": "t/1166457", "title": "\u8bf7\u6559\u5404\u4f4d\u4f6c\u4eec\u4e00\u4e2a\u5947\u602a\u7684\u540e\u7aef\u76f8\u5173\u7684\u6280\u672f\u95ee\u9898", "id": "t/1166457", "date_published": "2025-10-17T07:43:45+00:00", "content_html": "\u6700\u8fd1\u5f00\u53d1\u4e00\u4e2a\u65b0\u9879\u76ee \u6280\u672f\u6808\u662f python \u670d\u52a1\u6253\u5305 docker \u955c\u50cf\u653e\u5230\u4e86\u4e91\u4e0a\u90e8\u7f72 \u90e8\u7f72\u4e0a\u4e4b\u540e\u6ca1\u6709\u95ee\u9898 \u4f46\u662f\u9694\u4e86\u4e00\u6bb5\u65f6\u95f4\u5c31\u4f1a\u6709\u8d85\u65f6\u672a\u54cd\u5e94\u7684\u95ee\u9898 \u53ea\u8981\u91cd\u542f\u5bb9\u5668\u5c31\u7acb\u9a6c\u80fd\u6b63\u5e38\u8bbf\u95ee\u4e86 \u8fd9\u4e2a\u670d\u52a1\u672c\u8eab\u4e5f\u6ca1\u6709\u591a\u5927\u8bbf\u95ee\u91cf \u8bf7\u95ee\u5404\u4f4d\u4e00\u4e0b\u6392\u67e5\u601d\u8def \u4ee5\u53ca\u5927\u6982\u54ea\u91cc\u4f1a\u6709\u95ee\u9898
\n" }, { "author": { "url": "member/codists", "name": "codists", "avatar": "https://cdn.v2ex.com/avatar/8bba/467a/525158_large.png?m=1716029644" }, "url": "t/1165216", "title": "\u8fed\u4ee3\u5668\u7684\u5b9e\u9645\u5e94\u7528\u573a\u666f\u662f\u4ec0\u4e48\uff1f", "id": "t/1165216", "date_published": "2025-10-14T12:18:12+00:00", "content_html": "\u6700\u8fd1\u5728\u68b3\u7406 iterator \uff0c\u4e0d\u5f97\u4e0d\u8bf4\uff0c \u5373\u4f7f\u81ea\u5df1\u5199\u4e86\u5f88\u591a\u5e74\u7684\u4ee3\u7801\uff0c\u6211\u4ecd\u7136\u6ca1\u6709\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u770b\u5230\u81ea\u5b9a\u4e49\u7684\u8fed\u4ee3\u5668\u3002\u5373\u4f7f\u8bfb\u4e86\u5f88\u591a\u4e66\uff0c\u4f46\u662f\u8fd9\u4e9b\u4e66\u4e2d\u7684\u793a\u4f8b\u5927\u591a\u662f\u6ee5\u7afd\u5145\u6570\uff0c\u4e0d\u5177\u5907\u5b9e\u9645\u5e94\u7528\u610f\u4e49\u3002\u6240\u4ee5\u987a\u7740\u7f51\u7ebf\u722c\u4e0a V \u7ad9\u8bf7\u6559\u5404\u4f4d\u3002
\n\n\n\u5982\u679c\u4e00\u4e2a\u5bf9\u8c61\u5b9a\u4e49\u4e86
\n__iter__()\u65b9\u6cd5\u6216\u5b9a\u4e49\u4e86__getitem__()\u65b9\u6cd5\uff0c\u90a3\u4e48\u8fd9\u6837\u7684\u5bf9\u8c61\u79f0\u4e3a\u53ef\u8fed\u4ee3\u5bf9\u8c61(iterable)\u3002
\n\n\u5982\u679c\u4e00\u4e2a\u5bf9\u8c61\u5b9a\u4e49\u4e86
\n__iter__()\u65b9\u6cd5\u548c__next__()\u65b9\u6cd5\uff0c\u90a3\u4e48\u8fd9\u6837\u7684\u5bf9\u8c61\u79f0\u4e3a\u8fed\u4ee3\u5668(iterator)\u3002
\u6ce8\uff1a
\n1.\u540e\u7eed\u7684\u8ba8\u8bba\u90fd\u662f\u57fa\u4e8e\u4ee5\u4e0a\u4e24\u4e2a\u5b9a\u4e49\u3002
\n2.\u56e0\u8fed\u4ee3\u5668\u5e38\u548c\u53ef\u8fed\u4ee3\u5bf9\u8c61\u7ed3\u5408\u4f7f\u7528\uff0c\u6545\u5f15\u5982\u53ef\u8fed\u4ee3\u5bf9\u8c61\u8fd9\u4e00\u6982\u5ff5\uff0c\u4f46\u8fed\u4ee3\u5668\u7684\u6982\u5ff5\u5148\u4e8e\u751f\u6210\u5668(generator)\uff0c\u5728\u540e\u7eed\u7684\u8ba8\u8bba\u4e2d\u8bf7\u52ff\u6d89\u53ca\u751f\u6210\u5668\u3002
\npython 3 \u7684 range() \u662f\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff0c\u5176\u5b9e\u73b0\u4f7f\u7528\u4e86\u8fed\u4ee3\u5668\u3002\u4f7f\u7528\u8fed\u4ee3\u5668\u540e\u4e0d\u662f\u76f4\u63a5\u751f\u6210\u5217\u8868\uff0c\u8282\u7701\u4e86\u5185\u5b58\uff0c\u4f53\u73b0\u4e86\u8fed\u4ee3\u5668\u7684\u5e94\u7528\u610f\u4e49\u3002
\n\u300a Learn Python Programming(4th)\u300b \u7b2c 246 \u9875\uff1a
\nclass OddEven:\n def __init__(self, data):\n self._data = data\n self.indexes = list(range(0, len(data), 2)) + list(range(1, len(data), 2))\n\n def __iter__(self):\n return self\n\n def __next__(self):\n if self.indexes:\n return self._data[self.indexes.pop(0)]\n raise StopIteration\n\n\n# Testing the OddEven class\noddeven = OddEven(\"0123456789\")\nprint(\"\".join(c for c in oddeven)) # 0246813579\n\noddeven = OddEven(\"ABCD\") # or manually...\nit = iter(oddeven) # this calls oddeven.__iter__ internally\nprint(next(it)) # A\nprint(next(it)) # C\nprint(next(it)) # B\nprint(next(it)) # D\n\n\n\u8be5\u793a\u4f8b\u867d\u7136\u521b\u5efa\u4e86\u4e00\u4e2a\u8fed\u4ee3\u5668\uff0c\u4f46\u5c31\u529f\u80fd\u800c\u8a00\u5176\u5b9e\u5c31\u662f\u201c\u5c06\u5947\u6570\u4f4d\u7f6e\u7684\u5b57\u7b26\u653e\u5728\u524d\u534a\u6bb5\uff0c\u5c06\u5076\u6570\u4f4d\u7f6e\u7684\u5b57\u7b26\u653e\u5728\u540e\u534a\u6bb5\u201d\uff0c\u5b8c\u5168\u6ca1\u6709\u5fc5\u8981\u4f7f\u7528\u8fed\u4ee3\u5668\u3002\u5173\u4e8e\u8fed\u4ee3\u5668\u7684\u5b9e\u529b\uff0c\u672c\u4eba\u770b\u5230\u7684\u5927\u591a\u662f\u8fd9\u6837\u7684\u2014\u2014\u6beb\u65e0\u5b9e\u9645\u5e94\u7528\u610f\u4e49\uff0c\u4ee4\u4eba\u6df1\u6076\u75db\u7edd\uff01
\nPEP 234 \u4e2d\u5199\u5230 iterator \u7684 virtues \u6709:
\n\n\n\n
\n- It provides an extensible iterator interface.
\n- It allows performance enhancements to list iteration.
\n- It allows big performance enhancements to dictionary iteration.
\n- It allows one to provide an interface for just iteration without pretending to provide random access to elements.
\n- It is backward-compatible with all existing user-defined classes and extension objects that emulate sequences and mappings, even mappings that only implement a subset of {
\n__getitem__,keys,values,items}.- It makes code iterating over non-sequence collections more concise and readable.
\n
\u4e2d\u8bd1\u7248\uff1a
\n\n\n\u5982\u679c\u5305\u542b\u8be5\u63d0\u6848\u7684\u6240\u6709\u90e8\u5206\uff0c\u5219\u4f1a\u4ee5\u4e00\u81f4\u4e14\u7075\u6d3b\u7684\u65b9\u5f0f\u89e3\u51b3\u8bb8\u591a\u95ee\u9898\u3002\u5176\u4e3b\u8981\u4f18\u70b9\u5305\u62ec\u4ee5\u4e0b\u56db\u70b9\u2014\u2014\u4e0d\uff0c\u4e94\u70b9\u2014\u2014\u4e0d\uff0c\u516d\u70b9
\n\n
\n- \u5b83\u63d0\u4f9b\u4e86\u4e00\u4e2a\u53ef\u6269\u5c55\u7684\u8fed\u4ee3\u5668\u63a5\u53e3\u3002
\n- \u5b83\u5141\u8bb8\u5bf9\u5217\u8868\u8fed\u4ee3\u8fdb\u884c\u6027\u80fd\u4f18\u5316\u3002
\n- \u5b83\u5141\u8bb8\u5bf9\u5b57\u5178\u8fed\u4ee3\u8fdb\u884c\u5927\u5e45\u5ea6\u6027\u80fd\u63d0\u5347\u3002
\n- \u5b83\u5141\u8bb8\u4e3a\u4ec5\u8fed\u4ee3\u63d0\u4f9b\u63a5\u53e3\uff0c\u800c\u65e0\u9700\u5047\u88c5\u63d0\u4f9b\u5bf9\u5143\u7d20\u7684\u968f\u673a\u8bbf\u95ee\u3002
\n- \u5b83\u4e0e\u6240\u6709\u73b0\u6709\u7684\u7528\u6237\u5b9a\u4e49\u7c7b\u548c\u6a21\u62df\u5e8f\u5217\u548c\u6620\u5c04\u7684\u6269\u5c55\u5bf9\u8c61\u5411\u540e\u517c\u5bb9\uff0c\u5373\u4f7f\u662f\u4ec5\u5b9e\u73b0\u4e86 {
\n__getitem__,keys,values,items} \u5b50\u96c6\u7684\u6620\u5c04\u3002- \u5b83\u4f7f\u904d\u5386\u975e\u5e8f\u5217\u96c6\u5408\u7684\u4ee3\u7801\u66f4\u52a0\u7b80\u6d01\u6613\u8bfb\u3002
\n
\u4e0a\u9762\u6240\u5217\u51fa\u7684\u4f18\u70b9\u8f83\u62bd\u8c61\uff0c\u5404\u4f4d\u80fd\u5426\u63d0\u4f9b\u4e00\u4e9b\u5177\u4f53\u7684\u4f8b\u5b50\uff1f
\n\u5404\u4f4d\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u662f\u5426\u81ea\u5df1\u5b9e\u73b0\u8fc7\u8fed\u4ee3\u5668\uff1f\u5982\u679c\u6709\u9ebb\u70e6\u63d0\u4f9b\u4e00\u4e9b\u4f8b\u5b50\u3002
\n[1] Python Document Glossary \uff0citerator\uff1a https://docs.python.org/3/glossary.html#term-iterator
\n[2] PEP 234 \u2013 Iterators\uff1a https://peps.python.org/pep-0234
\n[3] PEP 234 \u2013 \u8fed\u4ee3\u5668: https://peps.pythonlang.cn/pep-0234/
\n" }, { "author": { "url": "member/ljfdeguge", "name": "ljfdeguge", "avatar": "https://cdn.v2ex.com/gravatar/80296a9c1147e67bfe913ccf1877c4af?s=73&d=retro" }, "url": "t/1164684", "title": "\u5c0f\u767d\u6c42\u95ee\uff0c\u521a\u63a5\u89e6\u7f16\u7a0b\u9886\u57df\u6709\u4ec0\u4e48\u901f\u6210\u7684\u65b9\u5f0f\u5b66\u4e60\u5417\uff0c\u5b66\u57fa\u7840\u9636\u6bb5\u5e76\u4e0d\u592a\u60f3\u53bb\u7cfb\u7edf\u5b66\u4e60.", "id": "t/1164684", "date_published": "2025-10-12T12:58:43+00:00", "content_html": "\u5982\u679c\u627e\u4eba\u4e00\u5bf9\u4e00\u6765\u5b66\u4e60\u662f\u4e0d\u662f\u66f4\u597d
\n" }, { "author": { "url": "member/cnbatch", "name": "cnbatch", "avatar": "https://cdn.v2ex.com/gravatar/7eb06cdf719fb364a1dfbbaefc4f9d36?s=73&d=retro" }, "url": "t/1164315", "title": "\ud835\udf0bthon ( Python 3.14)", "id": "t/1164315", "date_published": "2025-10-10T16:14:49+00:00", "content_html": "\u7248\u672c\u53f7\u5341\u5206\u7279\u522b\uff0c\u521a\u597d\u5c31\u662f \ud835\udf0b
\n\u5df2\u7ecf\u6709\u4eba\u6539\u4e86\u4ee3\u7801\uff0c\u4e3a\u8fd9\u4e2a\u7248\u672c\u6dfb\u52a0\u4e13\u95e8\u7684\u540d\u79f0\uff1a\ud835\udf0bthon
\ngh-119535: Support \ud835\udf0bthon in Python 3.14 venvs
\n" }, { "author": { "url": "member/w568w", "name": "w568w", "avatar": "https://cdn.v2ex.com/gravatar/a07da489e1f63eaa83cded683786df23?s=73&d=retro" }, "url": "t/1163727", "date_modified": "2025-10-08T10:46:34+00:00", "content_html": "\u91cd\u5927\u66f4\u65b0\uff1a
\nmultiprocessing \u4f9d\u8d56\u7684\u53c8\u4e00\u6b65\uff0c\u8fd8\u6dfb\u52a0\u4e86 InterpreterPoolExecutor \u6765\u5e2e\u52a9\u7ba1\u7406\u591a\u4e2a\u89e3\u91ca\u5668\u7684\u5e76\u884c\uff1bimport ___ \u7684\u81ea\u52a8\u8865\u5168\uff1bpython\u00a0-m\u00a0asyncio\u00a0<ps|pstree>\u00a0<PID> \u529f\u80fd\u6765\u68c0\u67e5\u6b63\u5728\u8fd0\u884c\u7684\u5f02\u6b65 Python \u7a0b\u5e8f\u7684 async task \u6811\u3002\u66f4\u591a\u53ef\u5728\u8fd9\u91cc\u770b\u5230\uff1a https://docs.python.org/zh-cn/3.14/whatsnew/3.14.html
\n", "date_published": "2025-10-08T10:44:24+00:00", "title": "Python 3.14 \u5df2\u53d1\u5e03", "id": "t/1163727" }, { "author": { "url": "member/tangkikodo", "name": "tangkikodo", "avatar": "https://cdn.v2ex.com/avatar/1771/1b39/291907_large.png?m=1720273866" }, "url": "t/1163179", "title": "fastapi-router-viz, \u53ef\u89c6\u5316\u4f60\u7684 API \u5185\u4f9d\u8d56\u5173\u7cfb", "id": "t/1163179", "date_published": "2025-10-02T12:17:35+00:00", "content_html": "https://github.com/allmonday/fastapi-router-viz
\n\u5bf9\u4e8e\u9075\u5faa er \u6a21\u578b\u6765\u6784\u5efa\u89c6\u56fe\u6570\u636e\u7684\u9879\u76ee\uff0cfastapi-router-viz \u53ef\u4ee5\u4e3a\u4e86\u89e3 api \u8fd4\u56de\u7c7b\u578b\u95f4\u7684\u5173\u7cfb\u63d0\u4f9b\u5feb\u901f\uff0c\u76f4\u63a5\uff0c\u53ef\u4ea4\u4e92\u7684\u56fe\u6548\u679c\u3002
\n\u53ef\u4ee5\u901a\u8fc7\u70b9\u51fb\u8282\u70b9\u9ad8\u4eae\u5168\u90e8\u4e0a\u4e0b\u6e38\u94fe\u8def\uff0c \u4e86\u89e3 pydantic class \u7684\u4e0a\u4e0b\u6e38\u4f9d\u8d56\u60c5\u51b5
\nalt \u70b9\u51fb\u67e5\u770b\u8282\u70b9\u7684\u6e90\u4ee3\u7801\uff0c\u6216\u8005\u76f4\u63a5\u5728 vscode \u4e2d\u6253\u5f00
\n\u6839\u636e class + field name \u6765\u7cbe\u51c6\u5b9a\u4f4d\u6570\u636e\u88ab\u54ea\u4e9b\u9875\u9762/ \u63a5\u53e3\u4f7f\u7528
\n" }, { "author": { "url": "member/emisora", "name": "emisora", "avatar": "https://cdn.v2ex.com/gravatar/ca281e0365d35422bad0c541497b0783?s=73&d=retro" }, "url": "t/1162621", "date_modified": "2025-09-29T05:16:35+00:00", "content_html": "\u8fd9\u95ee\u9898\u90fd\u51fa\u73b0\u534a\u5e74\u4e86\u3002\u5c1d\u8bd5\u7528 AI \u89e3\u51b3\uff0c\u7ed9\u6211\u8bd5\u4e86\u534a\u5929\u8fd8\u90fd\u662f too many request.
\n\u6211\u7684\u7f51\u7edc\u662f\u53ef\u4ee5\u7528 gemini cli \u4e4b\u7c7b\u7684\uff0c\u6309\u7406\u8bf4\u5e94\u8be5\u4e0d\u662f\u7f51\u7edc\u95ee\u9898\u554a\u3002
\n\u7b80\u5355\u6d4b\u8bd5\u4ee3\u7801\u5982\u4e0b\uff1a
\nimport yfinance as yf\nimport pandas as pd\n\n# \u8bbe\u7f6e\u6c38\u8f89\u8d85\u5e02\u7684\u80a1\u7968\u4ee3\u7801\nticker = \"601933.SS\" # .SS \u8868\u793a\u4e0a\u6d77\u8bc1\u5238\u4ea4\u6613\u6240\n\n# \u521b\u5efa yfinance \u5bf9\u8c61\nstock = yf.Ticker(ticker)\n\n# \u83b7\u53d6\u5b9e\u65f6\u4ef7\u683c\uff08\u6700\u65b0\u6536\u76d8\u4ef7\u6216\u5f53\u524d\u4ef7\u683c\uff0c\u89c6\u5e02\u573a\u60c5\u51b5\u800c\u5b9a\uff09\ncurrent_price = stock.history(period=\"1d\")[\"Close\"].iloc[-1]\n\n# \u83b7\u53d6\u80a1\u7968\u7684\u8be6\u7ec6\u4fe1\u606f\uff08\u5305\u62ec\u516c\u53f8\u540d\u79f0\u7b49\uff09\ninfo = stock.info\n\n# \u8f93\u51fa\u7ed3\u679c\nprint(f\"\u6c38\u8f89\u8d85\u5e02 ({ticker}) \u7684\u5b9e\u65f6\u4ef7\u683c: {current_price:.2f} CNY\")\nprint(f\"\u516c\u53f8\u540d\u79f0: {info.get('shortName', '\u672a\u77e5')}\")\n\n\u8fd0\u884c\u5c31\u76f4\u63a5\u62a5\u9519\uff1a
\n line 11, in <module>\n current_price = stock.history(period=\"1d\")[\"Close\"].iloc[-1]\n ^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/opt/anaconda3/lib/python3.12/site-packages/yfinance/utils.py\", line 103, in wrapper\n result = func(*args, **kwargs)\n ^^^^^^^^^^^^^^^^^^^^^\n File \"/opt/anaconda3/lib/python3.12/site-packages/yfinance/base.py\", line 91, in history\n return self._lazy_load_price_history().history(*args, **kwargs)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/opt/anaconda3/lib/python3.12/site-packages/yfinance/utils.py\", line 103, in wrapper\n result = func(*args, **kwargs)\n ^^^^^^^^^^^^^^^^^^^^^\n File \"/opt/anaconda3/lib/python3.12/site-packages/yfinance/scrapers/history.py\", line 178, in history\n data = get_fn(\n ^^^^^^^\n File \"/opt/anaconda3/lib/python3.12/site-packages/yfinance/utils.py\", line 103, in wrapper\n result = func(*args, **kwargs)\n ^^^^^^^^^^^^^^^^^^^^^\n File \"/opt/anaconda3/lib/python3.12/site-packages/yfinance/data.py\", line 364, in get\n return self._make_request(url, request_method = self._session.get, user_agent_headers=user_agent_headers, params=\nparams, timeout=timeout)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/opt/anaconda3/lib/python3.12/site-packages/yfinance/utils.py\", line 103, in wrapper\n result = func(*args, **kwargs)\n ^^^^^^^^^^^^^^^^^^^^^\n File \"/opt/anaconda3/lib/python3.12/site-packages/yfinance/data.py\", line 424, in _make_request\n raise YFRateLimitError()\nyfinance.exceptions.YFRateLimitError: Too Many Requests. Rate limited. Try after a while.\n\n\u8fd9\u8981\u600e\u4e48\u89e3\u51b3\u5462\uff0c\u96be\u9053 yahoo \u7684 API \u5c01\u8fd9\u4e48\u4e25\u91cd\u554a\u3002\u6709\u6ca1\u6709\u77e5\u9053\u600e\u4e48\u89e3\u51b3\u7684\u8001\u5144\u554a\uff0c\u611f\u8c22\uff01
\n", "date_published": "2025-09-29T05:15:57+00:00", "title": "yfinance \u83b7\u53d6\u6570\u636e\u603b\u662f too many request \u65e0\u6cd5\u83b7\u53d6\u4ef7\u683c\u554a", "id": "t/1162621" }, { "author": { "url": "member/deng1xin2020", "name": "deng1xin2020", "avatar": "https://cdn.v2ex.com/avatar/f8b7/d5c0/475324_large.png?m=1733819907" }, "url": "t/1159945", "title": "\u5c0f\u767d\u6c42\u95ee\uff0c\u5e94\u8058 AI \u7b97\u6cd5\u5de5\u7a0b\u5e08\u8fd9\u7c7b\u5c97\u4f4d\u5e94\u8be5\u6709\u4ec0\u4e48\u57fa\u7840\u77e5\u8bc6", "id": "t/1159945", "date_published": "2025-09-17T06:54:59+00:00", "content_html": "\u79cb\u62db\u5728\u5373\uff0c\u672b\u6d41 211 \u7855\u63a7\u5236\u7c7b\u4e13\u4e1a\u505a\u7684\u53c8\u504f\u751f\u533b\u65b9\u5411\u7684\uff0c\u5e73\u5e38\u5c31\u662f\u6d89\u53ca\u7684\u6280\u672f\u9762\u4e0d\u591a\uff0c\u60f3\u4e86\u89e3\u4e00\u4e0b\u5e94\u8058\u7b97\u6cd5\u7c7b\u7684\u90fd\u9700\u8981\u638c\u63e1\u54ea\u4e9b\u57fa\u7840\u77e5\u8bc6\uff0c\u5927\u4f6c\u4eec\u522b\u9a82\uff0c\u60f3\u5b66\u4e60\u4e00\u4e0b\u4e0d\u884c\u6625\u62db\u7528\u5f97\u4e0a\u4e5f ok \uff0c\u5b9e\u5728\u662f\u4e0d\u60f3\u5728\u7701\u5185\u7684\u51e0\u4e2a\u79c1\u4f01\u7b49\u7740\u5de5\u8d44\u5012\u6302" }, { "author": { "url": "member/VforVendetta", "name": "VforVendetta", "avatar": "https://cdn.v2ex.com/avatar/5e1d/d362/451056_large.png?m=1718169471" }, "url": "t/1159424", "date_modified": "2025-09-15T11:09:02+00:00", "content_html": "\u53d1\u73b0 Celery 4.2.3 \u4e0d\u652f\u6301\u7c7b\u65b9\u6cd5
\n\u4f8b\u5b50\uff1a
\nclass Demo:\n \u00a0@app.task\n \u00a0@classmethod\n \u00a0def test(cls):\n \u00a0 \u00a0 \u00a0pass\n \n\nschedule \u6ce8\u518c\u4efb\u52a1\uff1a\nDemo.test\n", "date_published": "2025-09-15T11:08:13+00:00", "title": "Celery \u4e0d\u652f\u6301\u7c7b\u65b9\u6cd5\u5417\uff1f\u9759\u6001\u65b9\u6cd5\u5462", "id": "t/1159424" }, { "author": { "url": "member/zilingmio", "name": "zilingmio", "avatar": "https://cdn.v2ex.com/gravatar/2e678a68cea97b477b1dad875d47b54d?s=73&d=retro" }, "url": "t/1159007", "title": "Easy AI18n | \u66f4\u597d\u7528\u7684 Python3 i18n \u5e93", "id": "t/1159007", "date_published": "2025-09-13T10:55:21+00:00", "content_html": "\u76ee\u524d\u5df2\u6709 i18n \u5e93\u7684\u75db\u70b9
\ngettext \u4e0d\u652f\u6301\u52a8\u6001\u9009\u62e9\u8bed\u8a00 (\u6bd4\u5982 Bot \u9700\u8981\u6839\u636e\u7528\u6237\u9009\u62e9\u8bed\u8a00)f-string \u8bed\u6cd5, \u5199\u8d77\u6765\u4e0d\u591f\u4f18\u96c5, \u4e0d\u591f\u65b9\u4fbf\u6240\u4ee5, Easy AI18n \u8bde\u751f\u4e86, \u89e3\u51b3\u4e86\u4ee5\u4e0a\u6240\u6709\u75db\u70b9
\nEasy AI18n \u662f\u4e00\u4e2a\u73b0\u4ee3\u5316\u7684 Python3 \u56fd\u9645\u5316\u5de5\u5177\u5e93\uff0c\u652f\u6301 AI \u7ffb\u8bd1\u3001\u591a\u7528\u6237\u573a\u666f\u4ee5\u53ca\u5b8c\u6574\u7684\u5b57\u7b26\u4e32\u683c\u5f0f\u5316\u8bed\u6cd5\uff0c\u8ba9\u9879\u76ee\u5168\u7403\u5316\u53d8\u5f97\u66f4\u52a0\u4f18\u96c5\u81ea\u7136\u3002
\nhttps://github.com/z-mio/easy-ai18n
\n| \u5176\u4ed6 i18n \u5de5\u5177 | \nEasyAI18n | \n
|---|---|
\u9700\u624b\u52a8\u7ef4\u62a4\u7ffb\u8bd1\u5b57\u5178, \u5f00\u53d1\u6548\u7387\u4f4e | \n \u81ea\u52a8\u63d0\u53d6\u7ffb\u8bd1\u5185\u5bb9\uff0c\u65e0\u9700\u624b\u52a8\u7ef4\u62a4\u6587\u4ef6 | \n
\u4ec5\u652f\u6301\u90e8\u5206\u683c\u5f0f\u5316\u8bed\u6cd5 | \n \u5b8c\u5168\u652f\u6301\u6240\u6709\u683c\u5f0f\u5316\u8bed\u6cd5 | \n
\u4e0d\u652f\u6301\u5b9e\u65f6\u591a\u8bed\u8a00\u5207\u6362\uff0c\u4e0d\u9002\u7528\u4e8e\u591a\u7528\u6237\u573a\u666f | \n \u652f\u6301\u9ed8\u8ba4\u8bed\u8a00\u4e0e\u591a\u8bed\u8a00\u5207\u6362\uff0c\u9002\u914d\u591a\u7528\u6237\u73af\u5883 | \n
\u901a\u8fc7\u81ea\u5b9a\u4e49\u8bed\u8a00\u9009\u62e9\u5668, \u5728\u591a\u7528\u6237\u73af\u5883\u4e2d\u5b9e\u73b0\u52a8\u6001\u8bed\u8a00\u9009\u62e9:
\n/i18n.py:
from pyrogram.types import Message\nfrom easy_ai18n import EasyAI18n, PostLanguageSelector\n\n\nclass MyPostLanguageSelector(PostLanguageSelector):\n def __getitem__(self, msg: Message):\n lang = msg.from_user.language_code\n return super().__getitem__(lang)\n\n\ni18n = EasyAI18n()\n\n_ = i18n.i18n(post_lang_selector=MyPostLanguageSelector)\n\nif __name__ == \"__main__\":\n i18n.build(target_lang=['en', 'ru'])\n\n/bot.py:
@bot.on_message()\nasync def start(__, msg: Message):\n await msg.reply(_[msg](\"Hello, world!\"))\n\n" }, { "author": { "url": "member/justtokankan", "name": "justtokankan", "avatar": "https://cdn.v2ex.com/gravatar/093604938501985c15eeae3b64b8afb3?s=73&d=retro" }, "url": "t/1157599", "title": "\u6709\u6ca1\u6709\u4fbf\u5b9c\u7684\u4ee3\u7406 ip \u6c60\u554a\uff1f\u7528\u6765\u505a\u722c\u866b\u7528", "id": "t/1157599", "date_published": "2025-09-07T06:41:09+00:00", "content_html": "" }, { "author": { "url": "member/justtokankan", "name": "justtokankan", "avatar": "https://cdn.v2ex.com/gravatar/093604938501985c15eeae3b64b8afb3?s=73&d=retro" }, "url": "t/1157547", "title": "\u5728\u722c\u4e00\u4e9b\u6570\u636e\uff0c\u5982\u679c\u8bf7\u6c42\u8fc7\u4e8e\u9891\u7e41\uff0c\u5176\u5b9e\u4e5f\u4e0d\u662f\u7279\u522b\u9891\u7e41\uff0c\u5bb9\u6613\u88ab ip \u5c01\u7981\uff0c\u6709\u5565\u597d\u7528\u7684\u514d\u8d39 ip \u6c60\u5417\uff1f\u6216\u8005\u4ed8\u8d39\u7684\u4e5f\u884c", "id": "t/1157547", "date_published": "2025-09-06T16:14:06+00:00", "content_html": "RT \uff0c\u8c22\u8c22\u5404\u4f4d\u6709\u7ecf\u9a8c\u7684\u5927\u4f6c
\n" }, { "author": { "url": "member/harlen", "name": "harlen", "avatar": "https://cdn.v2ex.com/gravatar/743d3d0ecbb33a689f27e8b651d49d98?s=73&d=retro" }, "url": "t/1154163", "date_modified": "2025-08-22T08:06:29+00:00", "content_html": "\u5982\u9898\uff0c\u4ee3\u7801\u6b63\u5e38\u80fd\u8dd1\u7684\u3002\u4f46\u662f debug \u6a21\u5f0f pycharm \u4f1a\u81ea\u52a8\u6253\u5370\u5bf9\u8c61\u3002\u7136\u540e\u5c31\u5806\u6808\u6ea2\u51fa\u4e86\uff0c\n\u8fd8\u770b\u4e0d\u5230\u5177\u4f53\u662f\u4ec0\u4e48\u8c03\u7528\u5bfc\u81f4\u7684\u6ea2\u51fa\uff0c\u53ea\u6709
\n\u8fdb\u7a0b\u5df2\u7ed3\u675f\uff0c\u9000\u51fa\u4ee3\u7801\u4e3a -1073741571 (0xC00000FD) \u7684\u9000\u51fa\u7801\n\n", "date_published": "2025-08-22T02:46:18+00:00", "title": "pycharm debug \u7684\u65f6\u5019\u5982\u4f55\u907f\u514d\u6253\u5370\u5bf9\u8c61 \u5806\u6808\u6ea2\u51fa\u4e86\uff0c\u53ef\u80fd\u662f\u5faa\u73af\u5f15\u7528", "id": "t/1154163" }, { "author": { "url": "member/LastWise", "name": "LastWise", "avatar": "https://cdn.v2ex.com/avatar/e26f/c2b0/101756_large.png?m=1754272277" }, "url": "t/1153527", "title": "\u4eff\u7167 uv \u5199\u4e86\u4e2a\u5305\u7ba1\u7406\u5668\uff0c\u7528\u8fc7\u7684\u90fd\u8bf4\u597d", "id": "t/1153527", "date_published": "2025-08-19T11:46:06+00:00", "content_html": "\u559c\u6b22\u7684\u53ef\u4ee5 star \u4e00\u4e0b\u54c8\uff0c\u66f4\u5feb\u66f4\u5f3a
\n\n" }, { "author": { "url": "member/xgq89757", "name": "xgq89757", "avatar": "https://cdn.v2ex.com/avatar/12c4/9fa1/445828_large.png?m=1755226998" }, "url": "t/1152582", "date_modified": "2025-08-15T05:50:13+00:00", "content_html": "\u516c\u53f8 toB \u9879\u76ee python \u4e09\u65b9\u4f9d\u8d56\u6709 150+\uff0c\u6709\u6ca1\u6709\u6bd4\u8f83\u4f18\u96c5\u7684\u65b9\u5f0f\u80fd\u4e25\u683c\u6309\u7167 requirements.txt \uff08\u53ef\u80fd\u5b58\u5728\u7248\u672c\u51b2\u7a81\uff09\u590d\u73b0\u4f9d\u8d56\u73af\u5883\uff0cpip install -r requirements.txt \u6709\u4e2a\u95ee\u9898\u5c31\u662f\u6ca1\u51c6\u8fc7\u6bb5\u65f6\u95f4\u6784\u5efa\u51fa\u6765\u7684\u73af\u5883\u5c31\u548c requirements.txt \u4e2d\u7684\u4e0d\u4e00\u81f4\u4e86\u6709\u6ca1\u6709\u4e00\u8d77\u5b66\u6df1\u5ea6\u5b66\u4e60\u548c Transformer \u7684\uff0c\u6216\u8005\u9700\u8981\u5199\u8bba\u6587\u7684\uff0c\u6211\u4e70\u4e86\u5957\u6211\u89c9\u5f97\u8fd8\u4e0d\u9519\u7684\u8bfe\uff0c\u6211\u5df2\u7ecf\u57fa\u672c\u4e0a\u5b66\u5b8c\u4e86\uff0c\u4e5f\u624b\u64b8\u4e86\u51e0\u4e2a CNN \u3001LSTM \u3001Transformer \u7684\u6a21\u578b\u3002\u4f46\u662f\u8bfe 3K \u4e70\u7684\uff0c\u5c31\u60f3\u627e\u51e0\u4e2a\u60f3\u5b66\u7684\uff0c\u6211\u597d\u56de\u70b9\u672c\uff01
\n" }, { "author": { "url": "member/xuegy", "name": "xuegy", "avatar": "https://cdn.v2ex.com/gravatar/a14fd036007f13550119309d4ee7e0f1?s=73&d=retro" }, "url": "t/1151962", "title": "\u5c4e\u5c71\u914d\u7740\u8be6\u5c3d\u6587\u6863\uff0c\u771f\u60f3\u63d0\u6876\u8dd1\u8def\u4e86\u3002", "id": "t/1151962", "date_published": "2025-08-12T20:48:08+00:00", "content_html": "\u6211\u60f3\u4e86\u5f88\u4e45\u4e5f\u6ca1\u60f3\u660e\u767d\u4e3a\u4ec0\u4e48\u8981\u624b\u64b8\u4e00\u4e2a\u652f\u6301\u4f20\u5165 numpy \u8fdb\u884c\u8fd0\u7b97\u7684\u77e9\u9635\u7c7b\u800c\u4e0d\u662f\u76f4\u63a5\u7528 numpy \uff1f\n
>>> type({/})\n<class 'set'>\n>>> {/} == set()\nTrue\n\n\u611f\u89c9\u597d\u5947\u602a\u7684\u8bed\u6cd5\uff0c\uff0c\u4e3a\u5565\u975e\u8981\u5f15\u5165\u4e00\u4e2a\u7a7a set \u8bed\u6cd5\uff1f\uff1f\u6709\u5565\u7279\u522b\u5927\u7684\u597d\u5904\u5417\uff1f\uff1f set() \u4e5f\u633a\u77ed\u7684\u554a\uff1f\uff1f
\n" }, { "author": { "url": "member/JoryJoestar", "name": "JoryJoestar", "avatar": "https://cdn.v2ex.com/avatar/9df9/b154/686578_large.png?m=1732757498" }, "url": "t/1150953", "title": "\u6709\u6ca1\u6709\u722c\u866b\u738b\uff01\u53ef\u4ee5\u6559\u4e0b\u6211 Websocket \u600e\u4e48\u722c\u5417?", "id": "t/1150953", "date_published": "2025-08-08T03:12:35+00:00", "content_html": "\u60f3\u8981\u722c\u7684\u7f51\u7ad9\uff1a https://crushon.ai/character/7e388767-63c7-45e3-b922-53458b4ae4f7/chat
\n\u4e00\u76f4\u8bf7\u6c42 403 \uff0c\u96be\u53d7\uff0c\u641e\u4e0d\u5b9a\uff0c\u7528\u65e0\u5934 playwrihgt \uff0c\u53c8\u4e0d\u8fc7 cloudflare \uff0c\u8bf7\u6c42\u53c8\u88ab\u62d2\u7edd\uff0c\u96be\u641e\uff01
\n\u60f3\u8bf7\u6559\u4e00\u4e0b v2 \u7684\u5404\u4f4d\u4f6c\uff0c\u600e\u4e48\u722c\u8fd9\u4e2a\u7f51\u7ad9\u804a\u5929\u5bf9\u8bdd\u3002
\n" }, { "author": { "url": "member/AlanZ1997", "name": "AlanZ1997", "avatar": "https://cdn.v2ex.com/avatar/b363/8368/656071_large.png?m=1698224266" }, "url": "t/1150473", "title": "\u8fd9 AI\uff0c\u8ba9\u4ed6\u5e2e\u6211\u6539\u4e2a\u7b97\u6cd5\uff0c\u597d\u5bb6\u4f19\u628a\u6211\u5173\u952e\u4ee3\u7801\u7ed9\u6211\u8bef\u5220\u4e86\uff01", "id": "t/1150473", "date_published": "2025-08-06T11:14:05+00:00", "content_html": "
\n\u8ba9\u4ed6\u6539\u4e2a\u7b97\u6cd5\u4ee3\u7801\uff0c\u628a\u6211\u4ee3\u7801\u7ed9\u5220\u9519\u4e86\uff0c\u5bfc\u81f4\u6574\u4e2a\u5de5\u7a0b\u51fa\u73b0\u4e0d\u53ef\u63a7\u95ee\u9898
\u5982\u9898\uff0c\u9009\u6280\u672f\u6808 ing \uff0c\u4e0d\u77e5\u9053\u6709\u6ca1\u6709\u5751
\n" }, { "author": { "url": "member/xkwdm", "name": "xkwdm", "avatar": "https://cdn.v2ex.com/avatar/88b3/23fe/373377_large.png?m=1760922424" }, "url": "t/1149792", "title": "[ Python ] \u6279\u91cf\u628a\u4ee3\u7801\u52a0\u5165\u5230 head \u5143\u7d20\u91cc\u9762\u3002", "id": "t/1149792", "date_published": "2025-08-04T06:26:06+00:00", "content_html": "\u65e5\u5e38\u9700\u8981\u628a\u8c37\u6b4c\u8ddf\u8e2a\u4ee3\u7801\u52a0\u5165\u5230 head \u5143\u7d20\u91cc\u9762\uff0c\u6240\u4ee5\u501f\u52a9 AI \u5199\u4e86\u4e00\u4e2a\u5c0f\u5de5\u5177\u3002
\n1 \u3001\u628a\u9700\u8981\u52a0\u5165\u7684\u5185\u5bb9\u4fdd\u5b58\u5230 GACode.txt \u6587\u4ef6\u4e2d
\n2 \u3001\u6267\u884c\u4ee3\u7801\uff0c\u8f93\u5165\u76ee\u5f55\u5373\u53ef\u3002\uff08\u53ea\u4f1a\u4fee\u6539 html \u6269\u5c55\u540d\u7684\u6587\u4ef6\uff09
\nimport os\nimport re\nimport sys\nfrom pathlib import Path\n\ndef get_resource_path(relative_path):\n \"\"\"\u83b7\u53d6\u8d44\u6e90\u6587\u4ef6\u7684\u7edd\u5bf9\u8def\u5f84\uff0c\u652f\u6301 PyInstaller \u6253\u5305\"\"\"\n try:\n # PyInstaller \u521b\u5efa\u4e34\u65f6\u6587\u4ef6\u5939\uff0c\u5e76\u5c06\u8def\u5f84\u5b58\u50a8\u5728_MEIPASS \u4e2d\n base_path = sys._MEIPASS\n except Exception:\n base_path = os.path.abspath(\".\")\n return os.path.join(base_path, relative_path)\n\ndef check_and_add_google_analytics():\n \"\"\"\n \u68c0\u67e5\u6240\u6709 HTML \u6587\u4ef6\u662f\u5426\u5305\u542b Google Analytics \u4ee3\u7801\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u6dfb\u52a0\n \"\"\"\n # \u521d\u59cb\u5316\u7edf\u8ba1\u4fe1\u606f\n stats = {\n 'total': 0,\n 'modified': 0,\n 'skipped': 0,\n 'errors': 0\n }\n \n # \u4ece GACode.txt \u6587\u4ef6\u8bfb\u53d6 Google Analytics \u4ee3\u7801\n ga_code_file = get_resource_path('GACode.txt')\n \n try:\n with open(ga_code_file, 'r', encoding='utf-8') as f:\n ga_code = f.read().strip()\n except FileNotFoundError:\n print(f\"\u9519\u8bef\uff1a\u627e\u4e0d\u5230\u6587\u4ef6 {ga_code_file}\")\n stats['errors'] = 1\n return stats\n except Exception as e:\n print(f\"\u9519\u8bef\uff1a\u8bfb\u53d6 GA \u4ee3\u7801\u6587\u4ef6\u65f6\u51fa\u9519: {str(e)}\")\n stats['errors'] = 1\n return stats\n \n if not ga_code:\n print(\"\u9519\u8bef\uff1aGA \u4ee3\u7801\u6587\u4ef6\u4e3a\u7a7a\")\n stats['errors'] = 1\n return stats\n \n # \u83b7\u53d6\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709 HTML \u6587\u4ef6\n html_files = list(Path('.').glob('*.html'))\n stats['total'] = len(html_files)\n \n print(f\"\u627e\u5230 {len(html_files)} \u4e2a HTML \u6587\u4ef6\")\n \n for html_file in html_files:\n print(f\"\\n \u5904\u7406\u6587\u4ef6: {html_file}\")\n \n try:\n # \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\n with open(html_file, 'r', encoding='utf-8') as f:\n cOntent= f.read()\n \n # \u68c0\u67e5\u662f\u5426\u5df2\u7ecf\u5305\u542b Google Analytics \u4ee3\u7801\n if 'googletagmanager.com/gtag/js' in content:\n print(f\" \u2713 {html_file} \u5df2\u5305\u542b Google Analytics \u4ee3\u7801\uff0c\u8df3\u8fc7\")\n stats['skipped'] += 1\n continue\n \n # \u67e5\u627e</head>\u6807\u7b7e\u7684\u4f4d\u7f6e\n head_end_pattern = r'</head>'\n match = re.search(head_end_pattern, content, re.IGNORECASE)\n \n if not match:\n print(f\" \u2717 {html_file} \u672a\u627e\u5230</head>\u6807\u7b7e\uff0c\u8df3\u8fc7\")\n stats['errors'] += 1\n continue\n \n # \u5728</head>\u6807\u7b7e\u524d\u63d2\u5165 Google Analytics \u4ee3\u7801\n head_end_pos = match.start()\n new_cOntent= (\n content[:head_end_pos] +\n ' ' + ga_code + '\\n' +\n content[head_end_pos:]\n )\n \n # \u5199\u5165\u4fee\u6539\u540e\u7684\u5185\u5bb9\n with open(html_file, 'w', encoding='utf-8') as f:\n f.write(new_content)\n \n print(f\" \u2713 {html_file} \u5df2\u6210\u529f\u6dfb\u52a0 Google Analytics \u4ee3\u7801\")\n stats['modified'] += 1\n \n except Exception as e:\n print(f\" \u2717 \u5904\u7406 {html_file} \u65f6\u51fa\u9519: {str(e)}\")\n stats['errors'] += 1\n \n print(\"\\n \u5904\u7406\u5b8c\u6210\uff01\")\n return stats\n\nif __name__ == \"__main__\":\n try:\n # \u83b7\u53d6\u7528\u6237\u8f93\u5165\u7684\u76ee\u5f55\u8def\u5f84\n current_dir = input(\"\u8bf7\u8f93\u5165\u8981\u5904\u7406\u7684\u76ee\u5f55\u8def\u5f84: \").strip()\n \n # \u5982\u679c\u7528\u6237\u6ca1\u6709\u8f93\u5165\uff0c\u5219\u4f7f\u7528\u5f53\u524d\u76ee\u5f55\n if not current_dir:\n current_dir = os.getcwd()\n \n print(f\"\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55: {current_dir}\")\n \n # \u5207\u6362\u5230\u6307\u5b9a\u76ee\u5f55\n try:\n os.chdir(current_dir)\n except FileNotFoundError:\n print(f\"\u9519\u8bef\uff1a\u76ee\u5f55 '{current_dir}' \u4e0d\u5b58\u5728\")\n input(\"\\n \u6309\u56de\u8f66\u952e\u9000\u51fa...\")\n exit(1)\n except PermissionError:\n print(f\"\u9519\u8bef\uff1a\u6ca1\u6709\u6743\u9650\u8bbf\u95ee\u76ee\u5f55 '{current_dir}'\")\n input(\"\\n \u6309\u56de\u8f66\u952e\u9000\u51fa...\")\n exit(1)\n \n # \u68c0\u67e5\u662f\u5426\u5728\u5305\u542b HTML \u6587\u4ef6\u7684\u76ee\u5f55\u4e2d\n html_files = list(Path('.').glob('*.html'))\n if not html_files:\n print(\"\u5f53\u524d\u76ee\u5f55\u4e0b\u6ca1\u6709\u627e\u5230 HTML \u6587\u4ef6\uff0c\u8bf7\u786e\u4fdd\u5728\u6b63\u786e\u7684\u76ee\u5f55\u4e0b\u8fd0\u884c\u6b64\u811a\u672c\")\n input(\"\\n \u6309\u56de\u8f66\u952e\u9000\u51fa...\")\n exit(1)\n \n # \u6267\u884c\u6dfb\u52a0 Google Analytics \u4ee3\u7801\u7684\u64cd\u4f5c\n stats = check_and_add_google_analytics()\n \n # \u68c0\u67e5\u8fd4\u56de\u503c\u662f\u5426\u6709\u6548\n if stats is None:\n print(\"\\n\u26a0 \u51fd\u6570\u6267\u884c\u5f02\u5e38\uff0c\u65e0\u6cd5\u83b7\u53d6\u7edf\u8ba1\u4fe1\u606f\")\n stats = {'total': 0, 'modified': 0, 'skipped': 0, 'errors': 1}\n \n # \u663e\u793a\u7edf\u8ba1\u7ed3\u679c\n print(\"\\n=== \u6267\u884c\u7edf\u8ba1 ===\")\n print(f\"\u603b\u6587\u4ef6\u6570: {stats['total']}\")\n print(f\"\u6210\u529f\u4fee\u6539: {stats['modified']} \u4e2a\")\n print(f\"\u5df2\u5b58\u5728\u8df3\u8fc7: {stats['skipped']} \u4e2a\")\n print(f\"\u5904\u7406\u5931\u8d25: {stats['errors']} \u4e2a\")\n \n if stats['modified'] > 0:\n print(f\"\\n\u2713 \u6210\u529f\u4e3a {stats['modified']} \u4e2a HTML \u6587\u4ef6\u6dfb\u52a0\u4e86 Google Analytics \u4ee3\u7801\uff01\")\n elif stats['total'] > 0 and stats['skipped'] == stats['total']:\n print(\"\\n\u2713 \u6240\u6709 HTML \u6587\u4ef6\u90fd\u5df2\u5305\u542b Google Analytics \u4ee3\u7801\uff0c\u65e0\u9700\u4fee\u6539\u3002\")\n else:\n print(\"\\n\u26a0 \u6ca1\u6709\u6210\u529f\u4fee\u6539\u4efb\u4f55\u6587\u4ef6\uff0c\u8bf7\u68c0\u67e5\u6587\u4ef6\u683c\u5f0f\u6216\u6743\u9650\u3002\")\n \n print(\"\\n=== \u7a0b\u5e8f\u6267\u884c\u5b8c\u6210 ===\")\n input(\"\\n \u6309\u56de\u8f66\u952e\u9000\u51fa...\")\n \n except KeyboardInterrupt:\n print(\"\\n\\n \u7a0b\u5e8f\u88ab\u7528\u6237\u4e2d\u65ad\")\n input(\"\\n \u6309\u56de\u8f66\u952e\u9000\u51fa...\")\n except Exception as e:\n print(f\"\\n \u7a0b\u5e8f\u6267\u884c\u65f6\u53d1\u751f\u672a\u77e5\u9519\u8bef: {str(e)}\")\n input(\"\\n \u6309\u56de\u8f66\u952e\u9000\u51fa...\")\n\n\u6211\u5c31\u4e0d\u53d1\u6210\u54c1\u4e86\uff0c\u81ea\u884c\u6253\u5305\u54c8
\n" }, { "author": { "url": "member/llsquaer", "name": "llsquaer", "avatar": "https://cdn.v2ex.com/avatar/4f44/aff2/441252_large.png?m=1754124863" }, "url": "t/1149487", "date_modified": "2025-08-02T09:00:37+00:00", "content_html": "\u770b\u56fe
\nlogger \uff0crequests \u90fd\u5c5e\u4e8e\u7b2c\u4e09\u65b9\u6a21\u5757\u3002\u4f46\u662f logger \u5c31\u662f\u7ea2\u7ebf\u3002\u6700\u521d\u4ee5\u4e3a\u662f\u73af\u5883\u6ca1\u8bc6\u522b\uff0c\u4f46\u662f\u8fd0\u884c\u90fd\u662f\u6b63\u5e38\u7684\uff0c\u8fd9\u4e8b\u60c5\u5f88\u8d39\u89e3\u554a\u3002\u6709\u89e3\u51b3\u529e\u6cd5\u4e48\uff1f
\n\u548b\u4e2a\u6ca1\u56fe\uff0c\u8d34\u4e2a\u5730\u5740\u5427 https://imgur.com/C7tWIvh
\n", "date_published": "2025-08-02T08:59:45+00:00", "title": "pycharm \u4f7f\u7528 uv \u4f5c\u4e3a\u73af\u5883\u7ba1\u7406\uff0c\u51fa\u73b0\u5bfc\u5165\u5212\u7ea2\u7ebf\u3002", "id": "t/1149487" }, { "author": { "url": "member/XIVN1987", "name": "XIVN1987", "avatar": "https://cdn.v2ex.com/avatar/c4ce/3bc8/138148_large.png?m=1744512747" }, "url": "t/1148957", "title": "\u4e0b\u9762\u8fd9\u7bc7\u201c Python 3.14 new features\u201d\u5185\u5bb9\u597d\u50cf\u662f\u5047\u7684\uff0c\uff0c\u8c01\u8fd9\u4e48\u65e0\u804a\u641e\u8fd9\u79cd\u4e1c\u897f\uff1f\uff1f", "id": "t/1148957", "date_published": "2025-07-31T02:28:36+00:00", "content_html": "\u524d\u51e0\u5929\u5728\u77e5\u4e4e\u4e0a\u770b\u5230\u8fd9\u7bc7\u6587\u7ae0\uff0c\uff0c\u5f53\u65f6\u5b8c\u5168\u6ca1\u8003\u8651\u6587\u7ae0\u7684\u771f\u5b9e\u6027\uff0c\uff0c\u53ea\u662f\u89c9\u5f97 Python \u600e\u4e48\u52a0\u8fd9\u4e48\u591a\u5947\u8469\u8bed\u6cd5\uff0c\uff0c\u8981\u5b8c\u3002\u3002
\n\u4eca\u5929\u7a0d\u5fae\u641c\u4e86\u4e0b\uff0c\uff0c\u53d1\u73b0\u6587\u7ae0\u4e2d\u63d0\u5230\u7684 PEP 727 \u3001PEP 740 \u5e76\u4e0d\u662f\u6587\u7ae0\u4e2d\u63cf\u8ff0\u7684\u5185\u5bb9\u3002\u3002\u4f3c\u4e4e\u6574\u7bc7\u6587\u7ae0\u90fd\u662f\u80e1\u7f16\u4e71\u9020\u7684\u3002\u3002
\n\u641e\u4e0d\u61c2\u8c01\u4f1a\u5199\u8fd9\u79cd\u4e1c\u897f\uff1f\uff1f\u96be\u9053\u662f AI \u751f\u6210\u7684\uff1f\uff1f
\n
\u6b63\u5728\u5904\u7406\u4e00\u5ea7\u5c4e\u5c71\uff0c\u5927\u6982\u60c5\u51b5\u662f\u8fd9\u6837\u7684\u3002\u6709\u4e00\u4e2a\u81ea\u5b9a\u4e49\u7684class X\uff0c\u9700\u8981\u6539\u6389\u7684\u4e1c\u897f\u6ce8\u91ca\u5199\u7684\u662fy=Union[X, str]\uff0c\u5b9e\u9645\u60c5\u51b5\u4e5f\u662f\u4e24\u79cd\u7c7b\u578b\u5230\u5904\u90fd\u6df7\u5728\u4e00\u8d77\u6839\u672c\u5206\u4e0d\u6e05\u3002\u540e\u9762\u6240\u6709\u8ddfX\u7c7b\u6709\u5173\u7684\u65b9\u6cd5\u4e00\u70b9\u6ce8\u91ca\u6ca1\u5199\uff0c\u751a\u81f3\u90fd\u4e0d\u505a\u7c7b\u578b\u5224\u65ad\uff0c\u800c\u662f\u5927\u91cf\u7684\u4f7f\u7528getattr(y, 'name', y)\u628a\u6c34\u6405\u5f97\u66f4\u6d51\uff08\u5982\u679cy\u662f\u5b57\u7b26\u4e32\uff0c\u6ca1\u6709name\uff0c\u8fd4\u56de\u5b57\u7b26\u4e32\u672c\u8eab\u3002\u5426\u5219\u8fd4\u56dey.name\u4e5f\u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\uff09\u3002\u6700\u79bb\u8c31\u7684\u662f\u6574\u5ea7\u5c4e\u5c71\u8fd8\u914d\u4e86\u4e00\u5957 30 \u5206\u949f\u624d\u80fd\u8dd1\u5b8c\u7684 pytest \u3002
\u73b0\u5728\u9700\u8981\u628a\u6df7\u4e71\u7684y\u5206\u6210\u786e\u5b9a\u7c7b\u578b\u7684y\u548cy_str\uff0c\u4f7f\u7528 pydantic \u5f3a\u5236\u5b9a\u4e49\u6570\u636e\u7c7b\u578b\u6765\u4e00\u70b9\u70b9\u6392\u9519\u3002\u7136\u800c\u6539\u4e86\u51e0\u767e\u884c\u4ee5\u540e\uff0c\u6240\u6709\u8ddfX\u6709\u5173\u7684\u65b9\u6cd5\u90fd\u88ab\u8feb\u6539\u51fa\u4e24\u79cd\u7248\u672c\u7684\u3002pytest \u4e0d\u518d\u62a5\u7c7b\u578b\u9519\u8bef\u4e86\uff0c\u5374\u5f00\u59cb\u51fa\u73b0\u5404\u79cd\u79bb\u5947\u7684 bug \u6302\u6389\u3002
\u6709\u4ec0\u4e48\u66f4\u5f3a\u5927\u7684\u5de5\u5177\u53ef\u4ee5\u641e\u5b9a\u8fd9\u4ef6\u4e8b\u5417\uff1f\u6bd4\u5982\u540c\u6b65\u68c0\u6d4b\u4e24\u4e2a\u7248\u672c\u7684\u4ee3\u7801\uff0c\u770b\u4ece\u54ea\u4e00\u6b65\u5f00\u59cb\u4e24\u8fb9\u7684\u6570\u636e\u53d8\u5f97\u4e0d\u4e00\u81f4\u4e86\uff1f
\n" }, { "author": { "url": "member/a663", "name": "a663", "avatar": "https://cdn.v2ex.com/gravatar/7c6f0fb78586ded9bc4c05c114d0a458?s=73&d=retro" }, "url": "t/1148514", "title": "Django \u957f\u8017\u65f6\u4efb\u52a1\uff0c\u8c03\u7528 ORM \u65f6\u4f1a\u51fa\u73b0\"MySQL server has gone away\"\u95ee\u9898\u5982\u4f55\u89e3\u51b3\uff1f", "id": "t/1148514", "date_published": "2025-07-29T07:42:20+00:00", "content_html": "\u5f53 Django \u7ed3\u5408\u5f02\u6b65\u4efb\u52a1(\u5982 Celery \u6216\u8005 MQ \u7b49)\uff0c\u6267\u884c\u957f\u8017\u65f6\u4efb\u52a1\uff0cDjango \u4f1a\u4e3a\u8be5\u4efb\u52a1\u7684\u51fd\u6570\u7b2c\u4e00\u6b21\u8c03\u7528 ORM \u65f6\u5206\u914d\u4e00\u6761\u6570\u636e\u5e93\u8fde\u63a5\uff0c\u800c\u4e14\u8fd9\u4e2a\u8fde\u63a5\u5728 ORM \u8c03\u7528\u7ed3\u675f\u65f6\u4e0d\u4f1a\u7acb\u5373\u91ca\u653e\uff0c\u5f53\u4f60\u5728\u540c\u4e00\u4e2a\u4efb\u52a1(\u957f\u8017\u65f6)\u91cc\u5176\u4ed6\u5730\u65b9\u518d\u6b21\u8c03\u7528 ORM \u65f6\uff0c\u5c31\u4f1a\u51fa\u73b0\"MySQL server has gone away\"\u7684\u62a5\u9519(\u539f\u56e0\u662f MySQL \u4e3b\u52a8\u65ad\u5f00\u7684)
\n\u5b98\u65b9\u63a8\u8350\u89e3\u51b3\u65b9\u6848\uff1a\n\u5982\u679c\u5728 Django \u7684\u8bf7\u6c42-\u54cd\u5e94\u5468\u671f\u4e4b\u5916\u7684\u957f\u8fd0\u884c\u8fdb\u7a0b\u4e2d\u521b\u5efa\u4e86\u8fde\u63a5\uff0c\u8be5\u8fde\u63a5\u5c06\u4fdd\u6301\u6253\u5f00\u72b6\u6001\uff0c\u76f4\u5230\u663e\u5f0f\u5173\u95ed\u6216\u8d85\u65f6\u53d1\u751f\u3002\u4f60\u53ef\u4ee5\u4f7f\u7528 django.db.close_old_connections() \u6765\u5173\u95ed\u6240\u6709\u65e7\u7684\u6216\u4e0d\u53ef\u7528\u7684\u8fde\u63a5\u3002
\n\u6211\u89c9\u5f97\u592a low \u4e86\u3002\u7406\u8bba\u4e0a\uff0c\u53ea\u9700\u8981\u8bbe\u7f6e\u6bcf\u6b21\u8c03\u7528 ORM \u5f00\u59cb\u524d\u83b7\u53d6\u4e00\u6761\u8fde\u63a5\uff0c\u8c03\u7528\u7ed3\u675f\u540e\u5173\u95ed\u8fde\u63a5\u5373\u53ef\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\u3002
\n\u6709\u6ca1\u6709\u5927\u4f6c\u9047\u5230\u8fc7\u8fd9\u4e2a\u95ee\u9898\uff1f\u5982\u4f55\u66f4\u52a0\u4f18\u96c5\u7684\u89e3\u51b3\uff1f
\n" }, { "author": { "url": "member/OSmile555", "name": "OSmile555", "avatar": "https://cdn.v2ex.com/gravatar/497812eaa68819d290a9d289df844922?s=73&d=retro" }, "url": "t/1146375", "title": "PySide6 \u7adf\u7136\u80fd\u5f00\u53d1\u5b89\u5353 APP \u4e86", "id": "t/1146375", "date_published": "2025-07-19T15:00:14+00:00", "content_html": "\u6700\u8fd1\u53d1\u73b0\u4e86\u8fd9\u4e2a\u4e8b\u60c5\u3002\u6709\u70b9\u60ca\u8bb6\uff01
\n" }, { "author": { "url": "member/heyzenxu", "name": "heyzenxu", "avatar": "https://cdn.v2ex.com/avatar/7aaf/894a/717535_large.png?m=1752810181" }, "url": "t/1146074", "title": "\u66f4\u73b0\u4ee3\u7684 pytest", "id": "t/1146074", "date_published": "2025-07-18T03:43:51+00:00", "content_html": "pytest \u7684\u539f\u751f\u5c55\u793a\u4fe1\u606f\u8fd9\u4e48\u591a\u5e74\u4e86\u4e5f\u6ca1\u600e\u4e48\u53d8, \u6211\u53c2\u8003 nextest \u5199\u4e86\u63d2\u4ef6 pytest-modern, \u63d0\u4f9b\u66f4\u73b0\u4ee3\u5316\u7684\u8f93\u51fa
\n\n" }, { "author": { "url": "member/Soulboy", "name": "Soulboy", "avatar": "https://cdn.v2ex.com/avatar/4f99/f50f/712252_large.png?m=1752717366" }, "url": "t/1145738", "title": "psycopg2 \u67e5\u8be2 sql \u65f6\u62a5\u9519", "id": "t/1145738", "date_published": "2025-07-17T02:02:26+00:00", "content_html": "V \u53cb\u4eec\uff0c\u5e2e\u5fd9\u7ed9\u70b9\u6392\u67e5\u610f\u89c1
\n\u95ee\u9898\u4e0d\u662f\u5fc5\u73b0\u7684\uff0c\u5076\u5c14\u5c31\u51fa\u73b0\u4e00\u6b21
\n\u95ee\u4e86 AI \u7ed9\u7684\u4e5f\u662f\u6a21\u7cca\u7684\u7684\u56de\u7b54
\n\u8fde\u63a5 pg \u6570\u636e\u5e93\u7528\u7684\u662f pool = PooledDB()
\n\u6267\u884c\u4ee3\u7801\u5982\u4e0b
\n def dbQuery(self, sql):\n cOnn= pool.connection()\n cur = conn.cursor()\n cur.execute(sql)\n result = cur.fetchall()\n cur.close()\n conn.close()\n return result\n\n\u62a5\u9519\u5982\u4e0b\uff1a
\ncould not receive data from server: Software caused connection abort (0x00002745/10053)\n\nTraceback (most recent call last):\n File \"aaTestV5.py\", line 844, in process\n input_values = self.getInputValuesInfo()\n File \"aa_process.py\", line 117, in getInputValuesInfo\n order_list = super(tf, self).getInputValuesInfo()\n File \"aaTestV5.py\", line 555, in getInputValuesInfo\n results_fromno, no_list = self.getFromnoResult()\n File \"aa_process.py\", line 366, in getFromnoResult\n return self.getFromnoResultInner(False)\n File \"aa_process.py\", line 320, in getFromnoResultInner\n results_fromno, no_list = super(tf, self).getFromnoResult(True)\n File \"aaTestV5.py\", line 119, in getFromnoResult\n result_fromno1 = self.dbQuery(query_sql)\n File \"aa_process.py\", line 391, in dbQuery\n return super(tf, self).dbQuery(sql)\n File \"aaTestV5.py\", line 823, in dbQuery\n cur.execute(sql)\n File \"\\python\\lib\\site-packages\\dbutils\\steady_db.py\", line 598, in tough_method\n result = method(*args, **kwargs) # try to execute\npsycopg2.DatabaseError: could not receive data from server: Software caused connection abort (0x00002745/10053)\n\n" }, { "author": { "url": "member/iorilu", "name": "iorilu", "avatar": "https://cdn.v2ex.com/avatar/7121/0eb9/222090_large.png?m=1764896933" }, "url": "t/1145021", "title": "Python \u5b98\u65b9\u53d1\u5e03\u7248\u672c\u7ba1\u7406\u5de5\u5177 pymanager - \u7c7b\u4f3c pyenv, uv", "id": "t/1145021", "date_published": "2025-07-14T02:43:53+00:00", "content_html": "https://github.com/python/pymanager
\n\u597d\u50cf\u662f\u521a\u53d1\u5e03\u7684, \u6ca1\u770b\u5230\u6709\u4eba\u8ba8\u8bba, \u6211\u4e5f\u662f\u6628\u5929\u770b\u5230\u7684
\n\u76ee\u524d\u53ea\u652f\u6301 windows , \u4f46\u5b98\u65b9\u4ea7\u54c1\u5e94\u8be5\u4ee5\u540e\u4f1a\u652f\u6301 linux, mac \u628a
\n\u5b98\u65b9\u603b\u7b97\u8ba4\u8bc6\u5230 python \u7684\u7248\u672c\u7ba1\u7406\u662f\u4e2a\u95ee\u9898\u4e86
\n" }, { "author": { "url": "member/nikan999", "name": "nikan999", "avatar": "https://cdn.v2ex.com/gravatar/846367927cad6c16c6d160fa1fa262ce?s=73&d=retro" }, "url": "t/1144381", "title": "\u5982\u4f55\u4f7f\u7528\u7a0b\u5e8f\u8bc6\u522b\u89c6\u9891\u91cc\u9762\u662f\u5426\u542b\u6709\u6c34\u5370\u3001\u5b57\u5e55\uff1f", "id": "t/1144381", "date_published": "2025-07-10T12:28:48+00:00", "content_html": "\u6c34\u5370\u662f\u672a\u77e5\u7684\uff0c\u6709\u6ca1\u6709\u76f8\u5173\u6a21\u578b\u6216\u8005\u5de5\u5177\u53ef\u4ee5\u8bc6\u522b\u5462
\n" }, { "author": { "url": "member/chen1star", "name": "chen1star", "avatar": "https://cdn.v2ex.com/gravatar/436a64de0d09aa90d98072abb5330321?s=73&d=retro" }, "url": "t/1143886", "title": "\u6781\u77ed\u65f6\u95f4\u5185\u627e\u51fa\u76ee\u5f55\u4e0b\u6240\u6709\u5e26 vba \u4ee3\u7801\u7684 excel \u6587\u4ef6\uff0c\u5e76\u628a\u5b83\u4eec\u8f6c\u6362\u6210\u6ca1\u6709 vba \u4ee3\u7801\u7684 excel \u6587\u4ef6", "id": "t/1143886", "date_published": "2025-07-08T22:32:05+00:00", "content_html": "win11 \u4e2d\u6709\u4e00\u4e2a\u6587\u4ef6\u76ee\u5f55\uff0c\u8fd9\u4e2a\u6587\u4ef6\u76ee\u5f55\u4e0b\u6709\u5f88\u591a\u5b50\u76ee\u5f55\u4ee5\u53ca\u5b50\u76ee\u5f55\u7684\u5b50\u76ee\u5f55\u7b49\u7b49\uff0c\u5728\u8fd9\u4e9b\u76ee\u5f55\u4e2d\u6709\u8bb8\u591a\u5e26 vba \u4ee3\u7801\u7684 excel \u6587\u4ef6\uff0c\u4e5f\u6709\u8bb8\u591a\u4e0d\u5e26 vba \u7684 excel \u6587\u4ef6\uff0c\u5927\u7ea6\u51e0\u5341\u4e07\u4e2a\uff0c\u8fd9\u4e9b excel \u6587\u4ef6\u7684\u7248\u672c\u4e0d\u4e00\u6837\u3002\u73b0\u5728\u9700\u8981\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u5728\u6781\u77ed\u65f6\u95f4\u5185\u627e\u51fa\u76ee\u5f55\u4e0b\u6240\u6709\u5e26 vba \u4ee3\u7801\u7684 excel \u6587\u4ef6\uff0c\u5e76\u628a\u5b83\u4eec\u8f6c\u6362\u6210\u6ca1\u6709 vba \u4ee3\u7801\u7684 excel \u6587\u4ef6\uff0c\u4fdd\u6301\u539f\u6765\u7684\u6587\u4ef6\u7248\u672c\u548c\u539f\u6765\u7684\u6587\u4ef6\u540d\uff0c\u5927\u5bb6\u6709\u4ec0\u4e48\u597d\u7684\u65b9\u6848\uff1f
\n" }, { "author": { "url": "member/moxiaowei", "name": "moxiaowei", "avatar": "https://cdn.v2ex.com/avatar/fc95/69be/181581_large.png?m=1751954295" }, "url": "t/1143732", "title": "\u6a21\u578b\u5728\u6d4b\u8bd5\u96c6\u4e0a\u7684\u51c6\u786e\u7387\u5361\u5728 95%\u4e0a\u4e0d\u53bb\uff0c\u80fd\u60f3\u7684\u529e\u6cd5\u90fd\u8bd5\u8fc7\u4e86\u5c31\u662f\u4e0d\u884c\uff0c\u90fd 3 \u5929\u4e86\uff0c\u6c42\u5404\u4f4d\u5927\u4f6c\u5e2e\u6211\u770b\u4e0b\u6709\u6ca1\u6709\u4f18\u5316\u7684\u65b9\u6848\uff01\u8dea\u8c22!", "id": "t/1143732", "date_published": "2025-07-08T06:00:33+00:00", "content_html": "\u4f7f\u7528 SVHN \u7684\u6570\u636e\u96c6\u8fdb\u884c\u6a21\u578b\u7684\u8bad\u7ec3\uff0c\u4f46\u662f\u6574\u4e2a\u6a21\u578b\u5728\u8bad\u7ec3\u96c6\u4e0a\u7684\u51c6\u786e\u7387\u662f\u4e00\u76f4\u5728\u4e0a\u5347\u7684\uff0c\u4f46\u662f\u5230\u4e86\u6d4b\u8bd5\u96c6\u4e0a\u5c31\u4e00\u76f4\u5361\u5728 95%\uff0c\u90fd 3 \u5929\u4e86\uff0c\u6c42\u5404\u4f4d\u5927\u4f6c\u5e2e\u6211\u770b\u4e0b\u6709\u6ca1\u6709\u4f18\u5316\u7684\u65b9\u6848\uff01\u8dea\u8c22!
\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.distributed.checkpoint import load_state_dict\nfrom torch.hub import load_state_dict_from_url\nfrom torch.nn.modules.loss import _Loss\nfrom torch.optim import Optimizer\nfrom torch.utils.data import Dataset, random_split, DataLoader\nimport torchvision\nfrom torchvision.transforms import transforms\nimport torchvision.models as m\nimport matplotlib.pyplot as plt\nimport random\nimport gc # \u7528\u4e8e\u5783\u573e\u56de\u6536\nfrom torchinfo import summary\nimport numpy as np\nimport random\n\nimport gc\n\n# \u8bbe\u7f6e\u968f\u673a\u6570\u79cd\u5b50\nSEED = 420\nrandom.seed(SEED)\nnp.random.seed(SEED)\ntorch.manual_seed(SEED)\ntorch.cuda.manual_seed(SEED)\ntorch.cuda.manual_seed_all(SEED)\ntorch.backends.cudnn.deterministic = True\ntorch.backends.cudnn.benchmark = False\n\n# \u8bbe\u7f6e\u4f7f\u7528 gpu \u8fd8\u662f cpu \u8fdb\u884c\u8bad\u7ec3\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n\n# \u5b9a\u4e49\u8bad\u7ec3\u7684\u8bba\u8ff0\nepochs = 100\nlr = 0.0001\n\n# \u5b9a\u4e49\u6570\u636e\u96c6\u9700\u8981\u7684\u53c2\u6570\nbatchSize = 64\n\n# \u52a0\u8f7d\u8bad\u7ec3\u96c6\u9700\u8981\u7684\u6570\u636e\u8f6c\u6362\u5668\ntrainT = transforms.Compose([\n transforms.RandomCrop(28),\n transforms.RandomRotation(degrees=[-15, 15]),\n transforms.ToTensor(),\n transforms.Normalize(mean = [0.4377, 0.4438, 0.4728], std = [0.1980, 0.2010, 0.1970])\n])\n\n# \u52a0\u8f7d\u6d4b\u8bd5\u96c6\u9700\u8981\u7684\u6570\u636e\u8f6c\u6362\u5668\ntestT = transforms.Compose([\n transforms.CenterCrop(28),\n transforms.ToTensor(),\n transforms.Normalize(mean = [0.4377, 0.4438, 0.4728], std = [0.1980, 0.2010, 0.1970])\n])\n\n# \u52a0\u8f7d\u8bad\u7ec3\u96c6\u6570\u636e\nsvhn_train = torchvision.datasets.SVHN(root='C:\\\\FashionMNIST'\n , split=\"train\"\n , download=True\n , transform=trainT\n )\n# \u52a0\u8f7d\u6d4b\u8bd5\u96c6\u6570\u636e\nsvhn_test = torchvision.datasets.SVHN(root='C:\\\\FashionMNIST'\n , split=\"test\"\n , download=True\n , transform=testT\n )\n\n# \u5b9a\u4e49\u795e\u7ecf\u7f51\u7edc\uff0c\u56e0\u4e3a\u6211\u4eec\u7684\u56fe\u7247\u7684\u5c3a\u5bf8\u548c\u6837\u672c\u6570\u91cf\u90fd\u4e0d\u662f\u5f88\u5927\uff0c\u6240\u4ee5\u9009\u62e9\u4ece ResNet18 \u548c Vgg16 \u4e2d\u62bd\u53d6\u5c42\u6765\u6784\u5efa\u7f51\u7edc\nresnet18_ = m.resnet18()\n\n\nclass MyResNet(nn.Module): # \u8fd9\u4e2a\u662f\u57fa\u4e8e ResNet18 \u6784\u5efa\u7684\u7f51\u7edc\n def __init__(self):\n super(MyResNet, self).__init__()\n self.block1 = nn.Sequential(\n nn.Conv2d(3, 64, 3, 1, 1),\n resnet18_.bn1,\n resnet18_.relu\n )\n\n self.block2 = resnet18_.layer2 # \u8fde\u6743\u91cd\u90fd\u4f1a\u590d\u7528\u8fc7\u6765\uff0c\u5728 resnet18_ = m.resnet18() \u8fd9\u513f\u5c31\u5df2\u7ecf\u521d\u59cb\u5316\u597d\u4e86\u6743\u91cd\u6570\u636e\uff01\n self.block3 = resnet18_.layer3\n self.block4 = resnet18_.layer4 # \u4ece Resnet18 \u4e2d\u54ea layer \u65b0\u589e\u5230\u81ea\u5df1\u7684\u6a21\u578b\u4e2d\n self.avgpool = resnet18_.avgpool\n\n self.fc = nn.Linear(512, 10, True)\n\n def forward(self, x):\n x = self.block1(x)\n x = self.block2(x)\n x = self.block3(x)\n x = self.block4(x) # \u8fd9\u513f\u65b0\u589e\u4e00\u6761\u5904\u7406\u4ee3\u7801\n x = self.avgpool(x)\n x = x.view(-1, 512)\n return self.fc(x)\n\n\nvgg16_ = m.vgg16()\n\n\nclass MyVgg(nn.Module): # \u8fd9\u4e2a\u662f\u57fa\u4e8e Vgg16 \u6784\u5efa\u7684\u7f51\u7edc\n def __init__(self):\n super(MyVgg, self).__init__()\n\n self.features = nn.Sequential(\n *vgg16_.features[0:9],\n # \u4f7f\u7528*\u662f \u5c06 .features[0:9]\u63d0\u53d6\u51fa\u6765\u7684\u5c42\uff0c\u5168\u90e8\u53d6\u51fa\u6765\uff0c\u4e00\u4e2a\u4e2a\u653e\u5230\u5f53\u524d\u7684 Sequential \u4e2d\uff0c\u800c\u4e0d\u662f\u7ec4\u6210\u4e00\u4e2a Sequential \u653e\u5230\u5f53\u524d\u7684 Sequential \u4e2d\uff01\n nn.Conv2d(128, 128, 3, 1, 1),\n nn.ReLU(inplace=True),\n nn.MaxPool2d(2, 2, padding=0, dilation=1, ceil_mode=False)\n )\n self.avgpool = vgg16_.avgpool\n\n self.fc = nn.Sequential(\n nn.Linear(6272, 4096, True),\n *vgg16_.classifier[1:6],\n nn.Linear(4096, 10, True)\n )\n\n def forward(self, x):\n x = self.features(x)\n x = self.avgpool(x)\n x = x.view(-1, 6272)\n x = self.fc(x)\n return x\n\n\n# summary(MyVgg(), input_size=(10, 3, 28, 28)) # \u4e00\u5b9a\u8981\uff0c\u5b9e\u4f8b\u5316\u8dd1\u4e00\u4e0b\uff0c\u770b\u770b\u6709\u6ca1\u6709\u95ee\u9898\uff01\n\n\nclass earlyStopping():\n\n def __init__(self, patience=5, tol=0.0005):\n # \u5f53\u8fde\u7eed patience=5 \u6b21\uff0c\u672c\u8f6e\u6b21\u7684\u8fed\u4ee3\u7684\u635f\u5931\u4e0e\u5386\u53f2\u6700\u5c0f\u7684\u635f\u5931\u7684\u5dee\u503c\u5927\u4e8e 0.0005 \u8fd9\u4e2a\u9608\u503c\uff0c\u5c31\u4f1a\u505c\u6b62\u8bad\u7ec3\n self.patience = patience\n self.tol = tol\n self.counter = 0 # \u8ba1\u6570\u5668\n self.lowest_loss = None # \u8bb0\u5f55\u5386\u53f2\u6700\u5c0f\u635f\u5931\n self.early_stop = False # \u9700\u8981\u8fd4\u56de\u662f\u5426\u9700\u8981\u63d0\u524d\u505c\u6b62\n\n def __call__(self, val_loss): # val_loss \u662f\u8bb0\u5f55\u6d4b\u8bd5\u96c6\u6216\u8bad\u7ec3\u96c6\u4e0a\u4e00\u6b21 epoch \u7684\u635f\u5931\n if self.lowest_loss is None:\n self.lowest_loss = val_loss\n elif self.lowest_loss - val_loss > self.tol:\n self.lowest_loss = val_loss\n self.counter = 0\n elif self.lowest_loss - val_loss < self.tol:\n self.counter += 1\n print('Notice: Early stopping counter {} of {}'.format(self.counter, self.patience))\n\n if self.counter >= self.patience:\n print('Notice: Early stopping counter Active')\n self.early_stop = True\n return self.early_stop\n\n\n# \u5b9a\u4e49\u8bad\u7ec3\u51fd\u6570\ndef fit(net: nn.Module, lossFunc: _Loss, op: Optimizer, trainData: DataLoader, testData: DataLoader, epochs: int):\n transLost = [] # \u7528\u4e8e\u6536\u96c6\u6bcf\u8f6e\u8bad\u7ec3\u548c\u6d4b\u8bd5\u7684\u7ed3\u679c\uff0c\u7528\u4e8e\u540e\u9762\u753b\u56fe\u8868\u4f7f\u7528\n trainCorrect = []\n testLost = []\n testCorrect = []\n trainedSampleNum = 0\n\n # \u521d\u59cb\u5316 earlystopping \u7c7b\n early_stopping = earlyStopping(patience=15, tol=0.00000005)\n # \u521d\u59cb\u5316\u6d4b\u8bd5\u96c6\u7684\u5386\u53f2\u6700\u9ad8\u51c6\u786e\u7387\n test_highest_correct = None\n test_lowest_loss = None\n\n # \u83b7\u53d6\u5230\u6574\u4e2a\u8bad\u7ec3\u96c6\u4e2d\u7684\u6837\u672c\u6570\u91cf\n trainTotalNum = trainData.dataset.__len__()\n # \u83b7\u53d6\u5230\u6574\u4e2a\u6d4b\u8bd5\u96c6\u4e2d\u7684\u6837\u672c\u6570\u91cf\n testTotalNum = testData.dataset.__len__()\n\n for epoch in range(epochs):\n net.train()\n train_loss = 0\n train_correct = 0\n for batch_index, (data, target) in enumerate(trainData):\n data = data.to(device, non_blocking=True)\n target = target.to(device, non_blocking=True).view(data.shape[0]) # \u786e\u4fdd\u6807\u7b7e\u662f 1 \u7ef4\u7684\u7ed3\u6784\n trainRes = net(data) # \u7ecf\u8fc7\u5b66\u4e60\uff0c\u8fd9\u513f\u6bcf\u4e2a\u6837\u672c\u4f1a\u8f93\u51fa 10 \u4e2a\u7279\u5f81\u7ed3\u679c\u5bf9\u5e94\u7684\u6570\u636e(\u5982\u679c\u6a21\u578b\u4e2d\u6709 softmax \uff0c\u5c31\u662f\u6982\u7387)\uff0c\u53ef\u4ee5\u7528\u4e8e\u540e\u7eed\u8ba1\u7b97\u51c6\u786e\u7387\n loss = lossFunc(trainRes, target)\n op.zero_grad() # \u6e05\u7a7a\u4f18\u5316\u5668\u4e0a\u7684\u68af\u5ea6\n loss.backward()\n op.step()\n # \u5f00\u59cb\u8ba1\u7b97\u51c6\u786e\u6570\uff0c\u5e76\u7d2f\u52a0\n yhat = torch.max(trainRes, 1)[1] # \u4ece trainRes \u4e00\u4e2a\u77e9\u9635\u4e2d\uff0c\u53d6\u51fa\u6bcf\u4e2a\u6837\u672c\u7684\u6700\u5927\u503c\u548c\u6700\u5927\u503c\u6240\u5728\u7684\u7d22\u5f15\uff0c\u5f97\u5230[1,2,1,4]\u8fd9\u79cd\u7c7b\u578b\u7684\u7ed3\u679c\n correct_num = torch.sum(\n yhat == target) # yhat \u3001target \u90fd\u662f\u4e00\u7ef4\u5f20\u91cf\uff0c\u4f7f\u7528 == \u4f1a\u6328\u4e2a\u5bf9\u6bd4\u5f20\u91cf\u4e2d\u7684\u5143\u7d20\u662f\u5426\u76f8\u7b49\uff0c\u6700\u7ec8\u5f97\u5230[False, True, Flase]\u8fd9\u6837\u7684\u6570\u636e\uff0c\u7136\u540e\u4f7f\u7528 torch.sum \u5c31\u53ef\u4ee5\u5f97\u5230\u4e00\u4e2a\u6570\u5b57\uff0c\u56e0\u4e3a True \u4e3a 1 \uff0cFalse \u4e3a 0 \u3002\n train_correct += correct_num # \u5c06\u51c6\u5907\u6570\u7d2f\u52a0\n # \u8ba1\u7b97\u635f\u5931\uff0c\u5e76\u7d2f\u52a0\n train_loss += loss.item() # \u8fd9\u513f\u9700\u8981\u5f97\u5230\u6240\u6709\u6837\u672c\u7684\u635f\u5931\u7684\u548c\n trainedSampleNum += data.shape[0]\n # print(\"\u672c\u6279\u6b21\u8bad\u7ec3\u635f\u5931\u4e3a\uff1a\", loss.item() / data.shape[0])\n if (batch_index + 1) % 125 == 0:\n # \u73b0\u5728\u8fdb\u884c\u5230\u4e86\u54ea\u4e2a epoch \u3001\u603b\u5171\u8981\u8bad\u7ec3\u591a\u5c11\u4e2a\u6837\u672c\u3001\u5df2\u7ecf\u8bad\u7ec3\u4e86\u591a\u5c11\u4e2a\u6837\u672c\u3001\u5df2\u8bad\u7ec3\u7684\u6837\u672c\u7684\u767e\u5206\u6bd4\n print(\"Epoch{}:{} / {} = ({:.0f}%)\".format(\n epoch + 1,\n trainedSampleNum,\n epochs * len(trainData) * batchSize,\n 100 * trainedSampleNum / (epochs * len(trainData) * batchSize)\n ))\n\n print(\"-------------------------------\")\n avg_correct = (float(train_correct) / trainTotalNum) * 100\n # print(\"\u672c\u8f6e\u8bad\u7ec3\u5e73\u5747\u51c6\u786e\u7387\uff1a\", avg_correct)\n trainCorrect.append(avg_correct)\n avg_loss = (float(train_loss) / trainTotalNum) * 100\n # print(\"\u672c\u8f6e\u8bad\u7ec3\u5e73\u5747\u635f\u5931\u7387\uff1a\", avg_loss)\n transLost.append(avg_loss)\n\n del data, target, train_loss, train_correct\n gc.collect()\n torch.cuda.empty_cache()\n\n # \u4e00\u8f6e\u8bad\u7ec3\u7ed3\u675f\uff0c\u5c31\u4f7f\u7528\u6d4b\u8bd5\u96c6\u8fdb\u884c\u6d4b\u8bd5\n net.eval()\n test_loss = 0\n test_correct = 0\n for batch_index, (test_data, test_target) in enumerate(testData):\n with torch.no_grad():\n test_data = test_data.to(device, non_blocking=True)\n test_target = test_target.to(device, non_blocking=True).view(test_data.shape[0]) # \u786e\u4fdd\u6807\u7b7e\u662f 1 \u7ef4\u7684\u7ed3\u6784\n testRes = net(test_data)\n loss = lossFunc(testRes, test_target)\n # \u8ba1\u7b97\u635f\u5931\uff0c\u5e76\u7d2f\u52a0\n test_loss += loss.item()\n # \u8ba1\u7b97\u51c6\u5907\u6570\uff0c\u5e76\u7d2f\u52a0\n yhat = torch.max(testRes, 1)[1] # \u4ece trainRes \u4e00\u4e2a\u77e9\u9635\u4e2d\uff0c\u53d6\u51fa\u6bcf\u4e2a\u6837\u672c\u7684\u6700\u5927\u503c\u548c\u6700\u5927\u503c\u6240\u5728\u7684\u7d22\u5f15\uff0c\u5f97\u5230[1,2,1,4]\u8fd9\u79cd\u7c7b\u578b\u7684\u7ed3\u679c\n correct_num = torch.sum(\n yhat == test_target) # yhat \u3001target \u90fd\u662f\u4e00\u7ef4\u5f20\u91cf\uff0c\u4f7f\u7528 == \u4f1a\u6328\u4e2a\u5bf9\u6bd4\u5f20\u91cf\u4e2d\u7684\u5143\u7d20\u662f\u5426\u76f8\u7b49\uff0c\u6700\u7ec8\u5f97\u5230[False, True, Flase]\u8fd9\u6837\u7684\u6570\u636e\uff0c\u7136\u540e\u4f7f\u7528 torch.sum \u5c31\u53ef\u4ee5\u5f97\u5230\u4e00\u4e2a\u6570\u5b57\uff0c\u56e0\u4e3a True \u4e3a 1 \uff0cFalse \u4e3a 0 \u3002\n test_correct += correct_num # \u5c06\u51c6\u5907\u6570\u7d2f\u52a0\n\n avg_test_correct = (float(test_correct) / testTotalNum) * 100\n # print(\"\u672c\u8f6e\u6d4b\u8bd5\u5e73\u5747\u51c6\u786e\u7387\uff1a\", avg_test_correct)\n testCorrect.append(avg_test_correct)\n avg_test_loss = (float(test_loss) / testTotalNum) * 100\n # print(\"\u672c\u8f6e\u6d4b\u8bd5\u5e73\u5747\u635f\u5931\u7387\uff1a\", avg_test_loss)\n testLost.append(avg_test_loss)\n\n print(\"\u672c\u8f6e\u8bad\u7ec3\u5e73\u5747\u51c6\u786e\u7387\uff1a{}, \u672c\u8f6e\u8bad\u7ec3\u5e73\u5747\u635f\u5931\u7387: {}, \u672c\u8f6e\u6d4b\u8bd5\u5e73\u5747\u51c6\u786e\u7387\uff1a{}, \u672c\u8f6e\u6d4b\u8bd5\u5e73\u5747\u635f\u5931\u7387\uff1a{}\".format(\n avg_correct, avg_loss, avg_test_correct, avg_test_loss))\n\n del test_data, test_target, test_loss, test_correct\n gc.collect()\n torch.cuda.empty_cache()\n\n # \u5982\u679c\u6d4b\u8bd5\u96c6\u635f\u5931\u51fa\u73b0\u65b0\u4f4e\u6216\u8005\u51c6\u786e\u7387\u51fa\u73b0\u65b0\u9ad8\uff0c\u5c31\u4fdd\u5b58\u5728\u6a21\u578b\u7684\u6743\u91cd\uff0c\u9632\u6b62\u4e2d\u9014\u65ad\u7535\u7b49\u539f\u56e0\u9700\u8981\u4ece\u5934\u518d\u6765\n if test_highest_correct is None:\n test_highest_correct = avg_test_correct\n if test_highest_correct < avg_test_correct:\n test_highest_correct = avg_test_correct\n torch.save(net.state_dict(), './v6/model-' + str(epoch + 1) + '.pth')\n print(\"model saved\")\n\n # \u6700\u597d\u5728\u6d4b\u8bd5\u96c6\u4e0a\u4f7f\u7528\u63d0\u524d\u505c\u6b62\uff0c\u5982\u679c\u4f7f\u7528\u8bad\u7ec3\u96c6\u65e0\u6cd5\u9884\u6d4b\u8fc7\u62df\u5408\u8fd9\u79cd\u60c5\u51b5\n early_stop = early_stopping(avg_test_loss) # \u8fd9\u513f\u4f7f\u7528\u63d0\u524d\u505c\u6b62\uff01\n if early_stop:\n break\n print(\"mission completed\")\n return transLost, trainCorrect, testLost, testCorrect\n\n\nmodel = MyResNet().to(device)\n# model.load_state_dict(torch.load(\"./v4/model-49.pth\"))\nloss_func = nn.CrossEntropyLoss(reduction='sum') # \u56e0\u4e3a\u6211\u4eec\u5728\u8bad\u7ec3\u51fd\u6570\u4e2d\uff0c\u5728\u8ba1\u7b97\u635f\u5931\u7684\u65f6\u5019\u662f\u8ba1\u7b97\u7684\u6bcf\u4e2a\u6837\u672c\u7684\u635f\u5931\u7684\u548c\uff0c\u6240\u4ee5\u8fd9\u513f\u9700\u8981\u4f7f\u7528 reduction='sum'\nopt = optim.RMSprop(model.parameters(), lr=lr, weight_decay=0.00005, momentum=0.0001)\n\ntrain_data = DataLoader(svhn_train, batch_size=batchSize, shuffle=True, drop_last=False, pin_memory=True)\ntest_data = DataLoader(svhn_test, batch_size=batchSize, shuffle=False, drop_last=False, pin_memory=True)\n\n# \u5f00\u59cb\u8bad\u7ec3\ntransLost, trainCorrect, testLost, testCorrect = fit(model, loss_func, opt, train_data, test_data, epochs)\n\n# \u8bad\u7ec3\u7ed3\u679c\u53ef\u89c6\u5316\nplt.plot(transLost, label='train loss')\nplt.plot(testLost, label='test loss')\nplt.plot(trainCorrect, label='train correcct')\nplt.plot(testCorrect, label='test correcct')\nplt.xlabel('Epoch')\nplt.ylabel('CrossEntropy Loss')\nplt.title('Training Loss')\nplt.legend()\nplt.grid(True)\nplt.show()\n" } ] }
ubao
msn
snddm
index
pchome
yahoo
rakuten
mypaper
meadowduck
bidyahoo
youbao
zxmzxm
asda
bnvcg
cvbfg
dfscv
mmhjk
xxddc
yybgb
zznbn
ccubao
uaitu
acv
GXCV
ET
GDG
YH
FG
BCVB
FJFH
CBRE
CBC
GDG
ET54
WRWR
RWER
WREW
WRWER
RWER
SDG
EW
SF
DSFSF
fbbs
ubao
fhd
dfg
ewr
dg
df
ewwr
ewwr
et
ruyut
utut
dfg
fgd
gdfgt
etg
dfgt
dfgd
ert4
gd
fgg
wr
235
wer3
we
vsdf
sdf
gdf
ert
xcv
sdf
rwer
hfd
dfg
cvb
rwf
afb
dfh
jgh
bmn
lgh
rty
gfds
cxv
xcv
xcs
vdas
fdf
fgd
cv
sdf
tert
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
shasha9178
shasha9178
shasha9178
shasha9178
shasha9178
liflif2
liflif2
liflif2
liflif2
liflif2
liblib3
liblib3
liblib3
liblib3
liblib3
zhazha444
zhazha444
zhazha444
zhazha444
zhazha444
dende5
dende
denden
denden2
denden21
fenfen9
fenf619
fen619
fenfe9
fe619
sdf
sdf
sdf
sdf
sdf
zhazh90
zhazh0
zhaa50
zha90
zh590
zho
zhoz
zhozh
zhozho
zhozho2
lislis
lls95
lili95
lils5
liss9
sdf0ty987
sdft876
sdft9876
sdf09876
sd0t9876
sdf0ty98
sdf0976
sdf0ty986
sdf0ty96
sdf0t76
sdf0876
df0ty98
sf0t876
sd0ty76
sdy76
sdf76
sdf0t76
sdf0ty9
sdf0ty98
sdf0ty987
sdf0ty98
sdf6676
sdf876
sd876
sd876
sdf6
sdf6
sdf9876
sdf0t
sdf06
sdf0ty9776
sdf0ty9776
sdf0ty76
sdf8876
sdf0t
sd6
sdf06
s688876
sd688
sdf86