Movatterモバイル変換


[0]ホーム

URL:


Following system colour schemeSelected dark colour schemeSelected light colour scheme

Python Enhancement Proposals

PEP 549 – Instance Descriptors

Author:
Larry Hastings <larry at hastings.org>
Discussions-To:
Python-Dev list
Status:
Rejected
Type:
Standards Track
Created:
04-Sep-2017
Python-Version:
3.7
Post-History:
04-Sep-2017

Table of Contents

Rejection Notice

https://mail.python.org/pipermail/python-dev/2017-November/150528.html

Abstract

Python’s descriptor protocol requires that descriptorsbe members of thetype of an object. This PEP proposesan extension to the descriptor protocol allowing use ofthe descriptor protocol for members ofinstances. Thiswould permit using properties in modules.

Rationale

Python’s descriptor protocol guides programmers towardselegant API design. If your class supports a data-likemember, and youmight someday need to run code whenchanging the member’s value, you’re encouraged tosimply declare it as a simple data member of the classfor now. If in the future you do need to run code, youcan change it to a “property”, and happily the API doesn’tchange.

But consider this second bit of best-practice Python API design:if you’re writing a singleton, don’t write a class, just buildyour code directly into a module. Don’t make your usersinstantiate a singleton class, don’t make your users have todereference through a singleton object stored in a module,just have module-level functions and module-level data.

Unfortunately these two best practices are in opposition.The problem is that properties aren’t supported on modules.Modules are instances of a single genericmodule type,and it’s not feasible to modify or subclass this type to adda property to one’s module. This means that programmersfacing this API design decision, where the data-like memberis a singleton stored in a module, must preemptively addugly “getters” and “setters” for the data.

Adding support for module properties in pure Python has recentlybecomepossible;as of Python 3.5, Python permits assigning to the__class__attribute of module objects, specifically for this purpose. Here’san example of using this functionality to add a property to a module:

importsys,typesclass_MyModuleType(types.ModuleType):@propertydefprop(self,instance,owner):...sys.modules[__name__].__class__=_MyModuleType

This works, and is supported behavior, but it’s clumsy and obscure.

This PEP proposes a per-type opt-in extension to the descriptorprotocol specifically designed to enable properties in modules.The mechanism is a way to honor the descriptor protocol formembers ofinstances of a class without the member being declaredas a class variable.

Although this is being proposed as a general mechanism, the authorcurrently only foresees this as being useful for module objects.

Implementation

The basic idea is simple: modify thetp_descr_get andtp_descr_setfunctions exposed byPyModule_Type to inspect the attribute interactedwith, and if it supports the descriptor protocol, call the relevantexposed function.

Our implementation faces two challenges:

  1. Since this code will be run every time an attribute is looked up on amethod, it needs to add very little overhead in the general case,where the object stored in the attribute is not a descriptor.
  2. Since functions are descriptors, we must take care tonot honorthe descriptor protocol for all objects. Otherwise, all module-levelfunctions will suddenly become bound to the module instance as ifthey were method calls on the module object. The module handle wouldbe passed in as a “self” argument to all module-level functions.

Both challenges can be solved with the same approach: we define a new“fast subclass” flag that means “This object is a descriptor, and itshould be honored directly when this object is looked up as anattribute of an instance”. So far this flag is only set on twotypes:property andcollections.abc.InstanceDescriptor.The latter is an abstract base class, whose only purpose isto allow user classes to inherit this “fast subclass” flag.

Prototype

A prototype of this functionality is under developmentat GitHub[github].

Acknowledgements

Armin Rigo essentially proposed this mechanism when presentedwith the idea of “module properties”, and educated the authorboth on the complexities of the problem and the proper solution.Nathaniel J. Smith pointed out the 3.5 extension about assigningto__class__ on module objects, and provided the example.

References

[github]
The branch is here:
https://github.com/larryhastings/cpython/tree/module-properties
A pull request against the main CPython repo is here:
https://github.com/python/cpython/pull/3534

Copyright

This document has been placed in the public domain.


Source:https://github.com/python/peps/blob/main/peps/pep-0549.rst

Last modified:2025-02-01 08:59:27 GMT


[8]ページ先頭

©2009-2025 Movatter.jp