diff options
author | Raymond Hettinger <rhettinger@users.noreply.github.com> | 2021-04-03 20:07:52 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-03 20:07:52 (GMT) |
commit | e4c8895ee5457b11f52841b79b51f3c3d6373fef (patch) | |
tree | 418191e654435cfaa3b2972eb4d3470ea16c63d1 /Doc/howto | |
parent | b2a91e0c9ee18b50cc86b21211c2258520a9f5d0 (diff) | |
download | cpython-e4c8895ee5457b11f52841b79b51f3c3d6373fef.zip cpython-e4c8895ee5457b11f52841b79b51f3c3d6373fef.tar.gz cpython-e4c8895ee5457b11f52841b79b51f3c3d6373fef.tar.bz2 |
Add more tests for the descriptor tutorial (GH-25164)
Diffstat (limited to 'Doc/howto')
-rw-r--r-- | Doc/howto/descriptor.rst | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index 420d9b9..819401e 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -281,7 +281,9 @@ The new class now logs access to both *name* and *age*: INFO:root:Updating 'name' to 'Catherine C' INFO:root:Updating 'age' to 20 -The two *Person* instances contain only the private names:: +The two *Person* instances contain only the private names: + +.. doctest:: >>> vars(pete) {'_name': 'Peter P', '_age': 10} @@ -710,6 +712,38 @@ perform attribute lookup by way of a helper function: raise return type(obj).__getattr__(obj, name) # __getattr__ +.. doctest:: + :hide: + + + >>> class ClassWithGetAttr: + ... x = 123 + ... def __getattr__(self, attr): + ... return attr.upper() + ... + >>> cw = ClassWithGetAttr() + >>> cw.y = 456 + >>> getattr_hook(cw, 'x') + 123 + >>> getattr_hook(cw, 'y') + 456 + >>> getattr_hook(cw, 'z') + 'Z' + + >>> class ClassWithoutGetAttr: + ... x = 123 + ... + >>> cwo = ClassWithoutGetAttr() + >>> cwo.y = 456 + >>> getattr_hook(cwo, 'x') + 123 + >>> getattr_hook(cwo, 'y') + 456 + >>> getattr_hook(cwo, 'z') + Traceback (most recent call last): + ... + AttributeError: 'ClassWithoutGetAttr' object has no attribute 'z' + So if :meth:`__getattr__` exists, it is called whenever :meth:`__getattribute__` raises :exc:`AttributeError` (either directly or in one of the descriptor calls). @@ -1139,8 +1173,8 @@ If you have ever wondered where *self* comes from in regular methods or where *cls* comes from in class methods, this is it! -Other kinds of methods ----------------------- +Kinds of methods +---------------- Non-data descriptors provide a simple mechanism for variations on the usual patterns of binding functions into methods. @@ -1193,19 +1227,19 @@ example calls are unexciting: class E: @staticmethod def f(x): - print(x) + return x * 10 .. doctest:: >>> E.f(3) - 3 + 30 >>> E().f(3) - 3 + 30 Using the non-data descriptor protocol, a pure Python version of :func:`staticmethod` would look like this: -.. doctest:: +.. testcode:: class StaticMethod: "Emulate PyStaticMethod_Type() in Objects/funcobject.c" @@ -1216,6 +1250,22 @@ Using the non-data descriptor protocol, a pure Python version of def __get__(self, obj, objtype=None): return self.f +.. testcode:: + :hide: + + class E_sim: + @StaticMethod + def f(x): + return x * 10 + +.. doctest:: + :hide: + + >>> E_sim.f(3) + 30 + >>> E_sim().f(3) + 30 + Class methods ------------- |