classproperty#
- class astropy.utils.decorators.classproperty(fget=None, doc=None, lazy=False)[source]#
Bases:
property
Similar to
property
, but allows class-level properties. That is, a property whose getter is like aclassmethod
.The wrapped method may explicitly use the
classmethod
decorator (which must become before this decorator), or theclassmethod
may be omitted (it is implicit through use of this decorator).Note
classproperty only works for read-only properties. It does not currently allow writeable/deletable properties, due to subtleties of how Python descriptors work. In order to implement such properties on a class a metaclass for that class must be implemented.
- Parameters:
- fget
callable()
The function that computes the value of this property (in particular, the function when this is used as a decorator) a la
property
.- doc
str
, optional The docstring for the property–by default inherited from the getter function.
- lazybool, optional
If True, caches the value returned by the first call to the getter function, so that it is only called once (used for lazy evaluation of an attribute). This is analogous to
lazyproperty
. Thelazy
argument can also be used whenclassproperty
is used as a decorator (see the third example below). When used in the decorator syntax this must be passed in as a keyword argument.
- fget
Examples
>>> class Foo: ... _bar_internal = 1 ... @classproperty ... def bar(cls): ... return cls._bar_internal + 1 ... >>> Foo.bar 2 >>> foo_instance = Foo() >>> foo_instance.bar 2 >>> foo_instance._bar_internal = 2 >>> foo_instance.bar # Ignores instance attributes 2
As previously noted, a
classproperty
is limited to implementing read-only attributes:>>> class Foo: ... _bar_internal = 1 ... @classproperty ... def bar(cls): ... return cls._bar_internal ... @bar.setter ... def bar(cls, value): ... cls._bar_internal = value ... Traceback (most recent call last): ... NotImplementedError: classproperty can only be read-only; use a metaclass to implement modifiable class-level properties
When the
lazy
option is used, the getter is only called once:>>> class Foo: ... @classproperty(lazy=True) ... def bar(cls): ... print("Performing complicated calculation") ... return 1 ... >>> Foo.bar Performing complicated calculation 1 >>> Foo.bar 1
If a subclass inherits a lazy
classproperty
the property is still re-evaluated for the subclass:>>> class FooSub(Foo): ... pass ... >>> FooSub.bar Performing complicated calculation 1 >>> FooSub.bar 1
Methods Summary
deleter
(fdel)Descriptor to obtain a copy of the property with a different deleter.
getter
(fget)Descriptor to obtain a copy of the property with a different getter.
setter
(fset)Descriptor to obtain a copy of the property with a different setter.
Methods Documentation