diff options
author | Géry Ogam <gery.ogam@gmail.com> | 2022-10-09 01:54:21 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-09 01:54:21 (GMT) |
commit | 2d2e01aa4cb72db8dabcd04e87f1e60b3597267e (patch) | |
tree | 6f9df59be0c0b7dfbcaef14f4b753ffaff31538e /Doc/howto | |
parent | 3378ebb933b00e1b95f1112511aa2cfb597a4ebf (diff) | |
download | cpython-2d2e01aa4cb72db8dabcd04e87f1e60b3597267e.zip cpython-2d2e01aa4cb72db8dabcd04e87f1e60b3597267e.tar.gz cpython-2d2e01aa4cb72db8dabcd04e87f1e60b3597267e.tar.bz2 |
Minor edits to the Descriptor HowTo Guide (GH-24901)
Co-authored-by: Raymond Hettinger <rhettinger@users.noreply.github.com>
Diffstat (limited to 'Doc/howto')
-rw-r--r-- | Doc/howto/descriptor.rst | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index 91a6c31..74710d9 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -847,7 +847,7 @@ afterwards, :meth:`__set_name__` will need to be called manually. ORM example ----------- -The following code is simplified skeleton showing how data descriptors could +The following code is a simplified skeleton showing how data descriptors could be used to implement an `object relational mapping <https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping>`_. @@ -1535,6 +1535,8 @@ by member descriptors: def __get__(self, obj, objtype=None): 'Emulate member_get() in Objects/descrobject.c' # Also see PyMember_GetOne() in Python/structmember.c + if obj is None: + return self value = obj._slotvalues[self.offset] if value is null: raise AttributeError(self.name) @@ -1563,13 +1565,13 @@ variables: class Type(type): 'Simulate how the type metaclass adds member objects for slots' - def __new__(mcls, clsname, bases, mapping): + def __new__(mcls, clsname, bases, mapping, **kwargs): 'Emulate type_new() in Objects/typeobject.c' # type_new() calls PyTypeReady() which calls add_methods() slot_names = mapping.get('slot_names', []) for offset, name in enumerate(slot_names): mapping[name] = Member(name, clsname, offset) - return type.__new__(mcls, clsname, bases, mapping) + return type.__new__(mcls, clsname, bases, mapping, **kwargs) The :meth:`object.__new__` method takes care of creating instances that have slots instead of an instance dictionary. Here is a rough simulation in pure @@ -1580,7 +1582,7 @@ Python: class Object: 'Simulate how object.__new__() allocates memory for __slots__' - def __new__(cls, *args): + def __new__(cls, *args, **kwargs): 'Emulate object_new() in Objects/typeobject.c' inst = super().__new__(cls) if hasattr(cls, 'slot_names'): @@ -1593,7 +1595,7 @@ Python: cls = type(self) if hasattr(cls, 'slot_names') and name not in cls.slot_names: raise AttributeError( - f'{type(self).__name__!r} object has no attribute {name!r}' + f'{cls.__name__!r} object has no attribute {name!r}' ) super().__setattr__(name, value) @@ -1602,7 +1604,7 @@ Python: cls = type(self) if hasattr(cls, 'slot_names') and name not in cls.slot_names: raise AttributeError( - f'{type(self).__name__!r} object has no attribute {name!r}' + f'{cls.__name__!r} object has no attribute {name!r}' ) super().__delattr__(name) |