OrderedDescriptorContainer

class astropy.utils.misc.OrderedDescriptorContainer(cls_name, bases, members)[ソース]

ベースクラス: type

バージョン 4.3 で非推奨: OrderedDescriptorContainerクラスは破棄されており,将来バージョンで削除される可能性がある.

その機能を __init_subclass__ そして __set_name__ Python 3.6に導入されたマジック方法。それらの機能をどのようにコピーするかについては,https://github.com.cn/astropy/astcopy/Issues/11094を参照されたい.

クラスがこのメタクラスを使用したい場合は,そのメタクラスを使用すべきである. OrderedDescriptor 属性,これらの属性は,クラスアスペクトで定義されている順序のクラス属性を“記憶”する.

それぞれのサブクラスは OrderedDescriptor has an attribute called ``_ CLASS_ATTRIBUTE_゚`。例えばもし私たちが

class ExampleDecorator(OrderedDescriptor):
    _class_attribute_ = '_examples_'

そしてある人が OrderedDescriptorContainer metaclass is created, it will automatically be assigned a class attribute _ Examples_゚`引用 `~collections.OrderedDict` 全ての事例を含む ``ExampleDecorator クラスアスペクトで定義され,それらに割り当てられた属性の名前からマッピングされる.

このメタクラスを用いてクラスをサブクラス化する場合,記述子DICT(すなわち, _examples_ 上の例では not 基底クラスから継承された記述子を含む.すなわち,デフォルトの場合,これはクラス主体で明示的に定義されている修飾子にのみ適用される.しかし、サブクラスは may 属性を定義する _inherit_decorators_ どんなリストですか。 OrderedDescriptor クラス、これらのクラス 当然だと思います。 基類から追加します。この態様の例については、以下の例を参照されたい。

実例.

>>> from astropy.utils import OrderedDescriptor, OrderedDescriptorContainer
>>> class TypedAttribute(OrderedDescriptor):
...     """
...     Attributes that may only be assigned objects of a specific type,
...     or subclasses thereof.  For some reason we care about their order.
...     """
...
...     _class_attribute_ = 'typed_attributes'
...     _name_attribute_ = 'name'
...     # A default name so that instances not attached to a class can
...     # still be repr'd; useful for debugging
...     name = '<unbound>'
...
...     def __init__(self, type):
...         # Make sure not to forget to call the super __init__
...         super().__init__()
...         self.type = type
...
...     def __get__(self, obj, objtype=None):
...         if obj is None:
...             return self
...         if self.name in obj.__dict__:
...             return obj.__dict__[self.name]
...         else:
...             raise AttributeError(self.name)
...
...     def __set__(self, obj, value):
...         if not isinstance(value, self.type):
...             raise ValueError('{0}.{1} must be of type {2!r}'.format(
...                 obj.__class__.__name__, self.name, self.type))
...         obj.__dict__[self.name] = value
...
...     def __delete__(self, obj):
...         if self.name in obj.__dict__:
...             del obj.__dict__[self.name]
...         else:
...             raise AttributeError(self.name)
...
...     def __repr__(self):
...         if isinstance(self.type, tuple) and len(self.type) > 1:
...             typestr = '({0})'.format(
...                 ', '.join(t.__name__ for t in self.type))
...         else:
...             typestr = self.type.__name__
...         return '<{0}(name={1}, type={2})>'.format(
...                 self.__class__.__name__, self.name, typestr)
...

次に以下のコードを用いた例示的なクラスを作成しましょう TypedAttribute **

>>> class Point2D(metaclass=OrderedDescriptorContainer):
...     x = TypedAttribute((float, int))
...     y = TypedAttribute((float, int))
...
...     def __init__(self, x, y):
...         self.x, self.y = x, y
...
>>> p1 = Point2D(1.0, 2.0)
>>> p1.x
1.0
>>> p1.y
2.0
>>> p2 = Point2D('a', 'b')  
Traceback (most recent call last):
    ...
ValueError: Point2D.x must be of type (float, int>)

これを見ました TypedAttribute 効果は多かれ少なかれ宣伝と同じだが、特別な点はない。何があるか見てみましょう OrderedDescriptorContainer 私たちのためにやってくれました

>>> Point2D.typed_attributes
OrderedDict([('x', <TypedAttribute(name=x, type=(float, int))>),
('y', <TypedAttribute(name=y, type=(float, int))>)])

サブクラスを作ると not デフォルトの場合、継承された記述子を追加する typed_attributes **

>>> class Point3D(Point2D):
...     z = TypedAttribute((float, int))
...
>>> Point3D.typed_attributes
OrderedDict([('z', <TypedAttribute(name=z, type=(float, int))>)])

しかしもし私たちが _inherit_descriptors_ 送信者. Point2D そしてこうします

>>> class Point3D(Point2D):
...     _inherit_descriptors_ = (TypedAttribute,)
...     z = TypedAttribute((float, int))
...
>>> Point3D.typed_attributes
OrderedDict([('x', <TypedAttribute(name=x, type=(float, int))>),
('y', <TypedAttribute(name=y, type=(float, int))>),
('z', <TypedAttribute(name=z, type=(float, int))>)])

注釈

これらの例から明らかなように、この構造は、タイプが OrderedDescriptorContainer 異なるものを複数使います OrderedDescriptor 同時に授業を受ける。

バージョン 4.3 で非推奨: OrderedDescriptorContainerクラスは破棄されており,将来バージョンで削除される可能性がある.

その機能を __init_subclass__ そして __set_name__ Python 3.6に導入されたマジック方法。それらの機能をどのようにコピーするかについては,https://github.com.cn/astropy/astcopy/Issues/11094を参照されたい.

新しいオブジェクトを作成して返します。正確な署名については,ヘルプ(タイプ)を参照されたい.