@@ -11,7 +11,7 @@ msgid ""
11
11
msgstr ""
12
12
"Project-Id-Version : Python 3.12\n "
13
13
"Report-Msgid-Bugs-To : \n "
14
- "POT-Creation-Date : 2025-02-07 14:52 +0000\n "
14
+ "POT-Creation-Date : 2025-02-14 14:53 +0000\n "
15
15
"PO-Revision-Date : 2024-05-11 00:32+0000\n "
16
16
"Last-Translator : Rafael Fontenelle <rffontenelle@gmail.com>, 2025\n "
17
17
"Language-Team : Chinese (China) (https://app.transifex.com/python-doc/teams/5390/zh_CN/)\n "
@@ -994,6 +994,9 @@ msgid ""
994
994
"method with an exception raising placeholder is enough to make it a data "
995
995
"descriptor."
996
996
msgstr ""
997
+ "为了使一个数据描述器只读,应同时定义 :meth:`~object.__get__` 和 :meth:`~object.__set__` 并在调用 "
998
+ ":meth:`~object.__set__` 时引发 :exc:`AttributeError`。 用引发异常的占位符定义 "
999
+ ":meth:`~object.__set__` 方法就足以使其成为一个数据描述器。"
997
1000
998
1001
#: ../../howto/descriptor.rst:552
999
1002
msgid "Overview of descriptor invocation"
@@ -1038,6 +1041,8 @@ msgid ""
1038
1041
"descriptors, then class variables, and lastly :meth:`~object.__getattr__` if"
1039
1042
" it is provided."
1040
1043
msgstr ""
1044
+ "实例查找会扫描命名空间链并给予数据描述器最高的优先级,然后是实例变量,然后是非数据描述器,最后是 "
1045
+ ":meth:`~object.__getattr__`,如果有提供的话。"
1041
1046
1042
1047
#: ../../howto/descriptor.rst:577
1043
1048
msgid ""
@@ -1111,6 +1116,9 @@ msgid ""
1111
1116
"``super().__getattribute__`` will bypass :meth:`~object.__getattr__` "
1112
1117
"entirely."
1113
1118
msgstr ""
1119
+ "注意,在 :meth:`~object.__getattribute__` 代码中没有 :meth:`~object.__getattr__` 钩子。 "
1120
+ "这就是为什么直接调用 :meth:`~object.__getattribute__` 或用 ``super().__getattribute__`` "
1121
+ "会彻底绕过 :meth:`~object.__getattr__`。"
1114
1122
1115
1123
#: ../../howto/descriptor.rst:723
1116
1124
msgid ""
@@ -1119,6 +1127,8 @@ msgid ""
1119
1127
":meth:`~object.__getattribute__` raises an :exc:`AttributeError`. Their "
1120
1128
"logic is encapsulated in a helper function:"
1121
1129
msgstr ""
1130
+ "相反,一旦 :meth:`~object.__getattribute__` 引发 :exc:`AttributeError` 则将由点运算符和 "
1131
+ ":func:`getattr` 函数来负责唤起 :meth:`~object.__getattr__`。 它们的逻辑封装在一个辅助函数中:"
1122
1132
1123
1133
#: ../../howto/descriptor.rst:728
1124
1134
msgid ""
@@ -1267,6 +1277,9 @@ msgid ""
1267
1277
"called with two arguments. The *owner* is the class where the descriptor is"
1268
1278
" used, and the *name* is the class variable the descriptor was assigned to."
1269
1279
msgstr ""
1280
+ "有时描述器需要知道它被赋值到哪个变量名。 当一个新类被创建时,:class:`type` 元类将扫描新类的字典。 "
1281
+ "如果其中有任何条目是描述器并且它们定义了 :meth:`~object.__set_name__`,则该方法被调用时将附带两个参数。 *owner* "
1282
+ "是使用该描述器的类,而 *name* 是该描述器被赋值到的变量。"
1270
1283
1271
1284
#: ../../howto/descriptor.rst:839
1272
1285
msgid ""
@@ -1282,6 +1295,8 @@ msgid ""
1282
1295
"place at the time of class creation. If descriptors are added to the class "
1283
1296
"afterwards, :meth:`~object.__set_name__` will need to be called manually."
1284
1297
msgstr ""
1298
+ "由于更新逻辑是在 :meth:`!type.__new__` 中,因此通知仅在类创建时发出。 之后如果将描述器添加到类中,则需要手动调用 "
1299
+ ":meth:`~object.__set_name__`。"
1285
1300
1286
1301
#: ../../howto/descriptor.rst:848
1287
1302
msgid "ORM example"
@@ -1337,6 +1352,8 @@ msgid ""
1337
1352
"<https://en.wikipedia.org/wiki/Database_model>`_ that describe the schema "
1338
1353
"for each table in a database:"
1339
1354
msgstr ""
1355
+ "我们可以使用 :class:`!Field` 类来定义描述了数据库中每张表的结构的 `模型 "
1356
+ "<https://en.wikipedia.org/wiki/Database_model>`_:"
1340
1357
1341
1358
#: ../../howto/descriptor.rst:877
1342
1359
msgid ""
@@ -1628,6 +1645,8 @@ msgid ""
1628
1645
" This means that functions are non-data descriptors that return bound "
1629
1646
"methods during dotted lookup from an instance. Here's how it works:"
1630
1647
msgstr ""
1648
+ "为支持方法的自动创建,函数会包括 :meth:`~object.__get__` 方法以便在属性访问期间绑定方法。 "
1649
+ "这意味着函数就是在通过实例进行点号查找期间返回所绑定方法的非数据描述器。 其运作方式是这样的:"
1631
1650
1632
1651
#: ../../howto/descriptor.rst:1190
1633
1652
msgid ""
@@ -1681,7 +1700,7 @@ msgid ""
1681
1700
"Accessing the function through the class dictionary does not invoke "
1682
1701
":meth:`~object.__get__`. Instead, it just returns the underlying function "
1683
1702
"object::"
1684
- msgstr ""
1703
+ msgstr "通过类字典访问函数不会唤起 :meth:`~object.__get__`。 相反,它只是返回下层的函数对象:: "
1685
1704
1686
1705
#: ../../howto/descriptor.rst:1220
1687
1706
msgid ""
@@ -1695,7 +1714,7 @@ msgstr ""
1695
1714
msgid ""
1696
1715
"Dotted access from a class calls :meth:`~object.__get__` which just returns "
1697
1716
"the underlying function unchanged::"
1698
- msgstr ""
1717
+ msgstr "通过类进行点号访问调用 :meth:`~object.__get__`,它将只原样返回下层的函数:: "
1699
1718
1700
1719
#: ../../howto/descriptor.rst:1226
1701
1720
msgid ""
@@ -1710,7 +1729,7 @@ msgid ""
1710
1729
"The interesting behavior occurs during dotted access from an instance. The "
1711
1730
"dotted lookup calls :meth:`~object.__get__` which returns a bound method "
1712
1731
"object::"
1713
- msgstr ""
1732
+ msgstr "有趣的行为发生在通过实例进行点号访问期间。 点号查找调用 :meth:`~object.__get__`,它将返回绑定的方法对象:: "
1714
1733
1715
1734
#: ../../howto/descriptor.rst:1232
1716
1735
msgid ""
@@ -1765,6 +1784,9 @@ msgid ""
1765
1784
"descriptor transforms an ``obj.f(*args)`` call into ``f(obj, *args)``. "
1766
1785
"Calling ``cls.f(*args)`` becomes ``f(*args)``."
1767
1786
msgstr ""
1787
+ "总结一下,函数具有 :meth:`~object.__get__` 方法以便在其作为属性被访问时可被转换为方法。 非数据描述器会将 "
1788
+ "``obj.f(*args)`` 调用转化为 ``f(obj, *args)``。 调用 ``cls.f(*args)`` 将变成 "
1789
+ "``f(*args)``。"
1768
1790
1769
1791
#: ../../howto/descriptor.rst:1260
1770
1792
msgid "This chart summarizes the binding and its two most useful variants:"
@@ -2289,12 +2311,47 @@ msgid ""
2289
2311
" 'Emulate member_repr() in Objects/descrobject.c'\n"
2290
2312
" return f'<Member {self.name!r} of {self.clsname!r}>'"
2291
2313
msgstr ""
2314
+ "null = object()\n"
2315
+ "\n"
2316
+ "class Member:\n"
2317
+ "\n"
2318
+ " def __init__(self, name, clsname, offset):\n"
2319
+ " 'Emulate PyMemberDef in Include/structmember.h'\n"
2320
+ " # 另请参阅 Objects/descrobject.c 中的 descr_new()\n"
2321
+ " self.name = name\n"
2322
+ " self.clsname = clsname\n"
2323
+ " self.offset = offset\n"
2324
+ "\n"
2325
+ " def __get__(self, obj, objtype=None):\n"
2326
+ " 'Emulate member_get() in Objects/descrobject.c'\n"
2327
+ " # 另请参阅 Python/structmember.c 中的 PyMember_GetOne()\n"
2328
+ " if obj is None:\n"
2329
+ " return self\n"
2330
+ " value = obj._slotvalues[self.offset]\n"
2331
+ " if value is null:\n"
2332
+ " raise AttributeError(self.name)\n"
2333
+ " return value\n"
2334
+ "\n"
2335
+ " def __set__(self, obj, value):\n"
2336
+ " 'Emulate member_set() in Objects/descrobject.c'\n"
2337
+ " obj._slotvalues[self.offset] = value\n"
2338
+ "\n"
2339
+ " def __delete__(self, obj):\n"
2340
+ " 'Emulate member_delete() in Objects/descrobject.c'\n"
2341
+ " value = obj._slotvalues[self.offset]\n"
2342
+ " if value is null:\n"
2343
+ " raise AttributeError(self.name)\n"
2344
+ " obj._slotvalues[self.offset] = null\n"
2345
+ "\n"
2346
+ " def __repr__(self):\n"
2347
+ " 'Emulate member_repr() in Objects/descrobject.c'\n"
2348
+ " return f'<Member {self.name!r} of {self.clsname!r}>'"
2292
2349
2293
2350
#: ../../howto/descriptor.rst:1685
2294
2351
msgid ""
2295
2352
"The :meth:`!type.__new__` method takes care of adding member objects to "
2296
2353
"class variables:"
2297
- msgstr ""
2354
+ msgstr ":meth:`!type.__new__` 方法负责将成员对象添加到类变量: "
2298
2355
2299
2356
#: ../../howto/descriptor.rst:1688
2300
2357
msgid ""
@@ -2309,6 +2366,16 @@ msgid ""
2309
2366
" mapping[name] = Member(name, clsname, offset)\n"
2310
2367
" return type.__new__(mcls, clsname, bases, mapping, **kwargs)"
2311
2368
msgstr ""
2369
+ "class Type(type):\n"
2370
+ " 'Simulate how the type metaclass adds member objects for slots'\n"
2371
+ "\n"
2372
+ " def __new__(mcls, clsname, bases, mapping, **kwargs):\n"
2373
+ " 'Emulate type_new() in Objects/typeobject.c'\n"
2374
+ " # type_new() 将调用 PyTypeReady(),后者将调用 add_methods()\n"
2375
+ " slot_names = mapping.get('slot_names', [])\n"
2376
+ " for offset, name in enumerate(slot_names):\n"
2377
+ " mapping[name] = Member(name, clsname, offset)\n"
2378
+ " return type.__new__(mcls, clsname, bases, mapping, **kwargs)"
2312
2379
2313
2380
#: ../../howto/descriptor.rst:1701
2314
2381
msgid ""
@@ -2348,12 +2415,41 @@ msgid ""
2348
2415
" )\n"
2349
2416
" super().__delattr__(name)"
2350
2417
msgstr ""
2418
+ "class Object:\n"
2419
+ " 'Simulate how object.__new__() allocates memory for __slots__'\n"
2420
+ "\n"
2421
+ " def __new__(cls, *args, **kwargs):\n"
2422
+ " 'Emulate object_new() in Objects/typeobject.c'\n"
2423
+ " inst = super().__new__(cls)\n"
2424
+ " if hasattr(cls, 'slot_names'):\n"
2425
+ " empty_slots = [null] * len(cls.slot_names)\n"
2426
+ " object.__setattr__(inst, '_slotvalues', empty_slots)\n"
2427
+ " return inst\n"
2428
+ "\n"
2429
+ " def __setattr__(self, name, value):\n"
2430
+ " 'Emulate _PyObject_GenericSetAttrWithDict() Objects/object.c'\n"
2431
+ " cls = type(self)\n"
2432
+ " if hasattr(cls, 'slot_names') and name not in cls.slot_names:\n"
2433
+ " raise AttributeError(\n"
2434
+ " f'{cls.__name__!r} object has no attribute {name!r}'\n"
2435
+ " )\n"
2436
+ " super().__setattr__(name, value)\n"
2437
+ "\n"
2438
+ " def __delattr__(self, name):\n"
2439
+ " 'Emulate _PyObject_GenericSetAttrWithDict() Objects/object.c'\n"
2440
+ " cls = type(self)\n"
2441
+ " if hasattr(cls, 'slot_names') and name not in cls.slot_names:\n"
2442
+ " raise AttributeError(\n"
2443
+ " f'{cls.__name__!r} object has no attribute {name!r}'\n"
2444
+ " )\n"
2445
+ " super().__delattr__(name)"
2351
2446
2352
2447
#: ../../howto/descriptor.rst:1736
2353
2448
msgid ""
2354
2449
"To use the simulation in a real class, just inherit from :class:`!Object` "
2355
2450
"and set the :term:`metaclass` to :class:`Type`:"
2356
2451
msgstr ""
2452
+ "要在真实的类中使用此模拟,只需从 :class:`!Object` 继承并将 :term:`metaclass` 设为 :class:`Type`:"
2357
2453
2358
2454
#: ../../howto/descriptor.rst:1739
2359
2455
msgid ""
@@ -2366,6 +2462,14 @@ msgid ""
2366
2462
" self.x = x\n"
2367
2463
" self.y = y"
2368
2464
msgstr ""
2465
+ "class H(Object, metaclass=Type):\n"
2466
+ " 'Instance variables stored in slots'\n"
2467
+ "\n"
2468
+ " slot_names = ['x', 'y']\n"
2469
+ "\n"
2470
+ " def __init__(self, x, y):\n"
2471
+ " self.x = x\n"
2472
+ " self.y = y"
2369
2473
2370
2474
#: ../../howto/descriptor.rst:1750
2371
2475
msgid ""
@@ -2383,6 +2487,14 @@ msgid ""
2383
2487
" 'x': <Member 'x' of 'H'>,\n"
2384
2488
" 'y': <Member 'y' of 'H'>}"
2385
2489
msgstr ""
2490
+ ">>> from pprint import pp\n"
2491
+ ">>> pp(dict(vars(H)))\n"
2492
+ "{'__module__': '__main__',\n"
2493
+ " '__doc__': 'Instance variables stored in slots',\n"
2494
+ " 'slot_names': ['x', 'y'],\n"
2495
+ " '__init__': <function H.__init__ at 0x7fb5d302f9d0>,\n"
2496
+ " 'x': <Member 'x' of 'H'>,\n"
2497
+ " 'y': <Member 'y' of 'H'>}"
2386
2498
2387
2499
#: ../../howto/descriptor.rst:1771
2388
2500
msgid ""
0 commit comments