What is a DynamicClassAttribute and how do I use it?

后端 未结 2 442
刺人心
刺人心 2021-02-02 09:53

As of Python 3.4, there is a descriptor called DynamicClassAttribute. The documentation states:

types.DynamicClassAttribute(fget=None, fset=None, fdel

2条回答
  •  花落未央
    2021-02-02 10:10

    What is a DynamicClassAttribute

    A DynamicClassAttribute is a descriptor that is similar to property. Dynamic is part of the name because you get different results based on whether you access it via the class or via the instance:

    • instance access is identical to property and simply runs whatever method was decorated, returning its result

    • class access raises an AttributeError; when this happens Python then searches every parent class (via the mro) looking for that attribute -- when it doesn't find it, it calls the class' metaclass's __getattr__ for one last shot at finding the attribute. __getattr__ can, of course, do whatever it wants -- in the case of EnumMeta __getattr__ looks in the class' _member_map_ to see if the requested attribute is there, and returns it if it is. As a side note: all that searching had a severe performance impact, which is why we ended up putting all members that did not have name conflicts with DynamicClassAttributes in the Enum class' __dict__ after all.

    and how do I use it?

    You use it just like you would property -- the only difference is that you use it when creating a base class for other Enums. As an example, the Enum from aenum1 has three reserved names:

    • name
    • value
    • values

    values is there to support Enum members with multiple values. That class is effectively:

    class Enum(metaclass=EnumMeta):
    
        @DynamicClassAttribute
        def name(self):
            return self._name_
    
        @DynamicClassAttribute
        def value(self):
            return self._value_
    
        @DynamicClassAttribute
        def values(self):
            return self._values_
    

    and now any aenum.Enum can have a values member without messing up Enum..values.


    1 Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.

提交回复
热议问题