2

オブジェクトに属性を設定するときに型チェックを行う最も効率的な方法 (「効率的」は必ずしも高速ではなく、「エレガント」または「保守可能」を意味する) は何ですか?

を使用__slots__して許可された属性を定義できますが、どのようにタイプを制限すればよいですか?

確かに、各属性に対して「セッター」メソッドを作成できますが、型チェックは通常単純であるため、維持するのは少し面倒です。

だから私はこのようなことをしています:

import datetime

# ------------------------------------------------------------------------------
# MyCustomObject
# ------------------------------------------------------------------------------
class MyCustomObject(object):
    pass

# ------------------------------------------------------------------------------
# MyTypedObject
# ------------------------------------------------------------------------------
class MyTypedObject(object):     
    attr_types = {'id'         : int,
                  'start_time' : datetime.time,
                  'duration'   : float,
                  'reference'  : MyCustomObject,
                  'result'     : bool,
                  'details'    : str}

    __slots__ = attr_types.keys()

    # --------------------------------------------------------------------------
    # __setattr__
    # --------------------------------------------------------------------------
    def __setattr__(self, name, value):
        if name not in self.__slots__:
            raise AttributeError(
                "'%s' object has no attribute '%s'" 
                % (self.__class__.__name__, name))
        if type(value) is not self.attr_types[name]:
                raise TypeError(
                    "'%s' object attribute '%s' must be of type '%s'" 
                    % (self.__class__.__name__, name, 
                       self.attr_types[name].__name__))
        # call __setattr__ on parent class
        super(MyTypedObject, self).__setattr__(name, value)

私の目的のためにはうまくいきます:

>>> my_typed_object            = MyTypedObject()
>>> my_typed_object.id         = "XYZ"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 28, in __setattr__
TypeError: 'MyTypedObject' object attribute 'id' must be of type 'int'
>>> my_typed_object.id         = 123
>>> my_typed_object.reference  = []
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 28, in __setattr__
TypeError: 'MyTypedObject' object attribute 'reference' must be of type 'MyCustomObject'
>>> my_typed_object.reference  = MyCustomObject()
>>> my_typed_object.start_time = "13:45"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 28, in __setattr__
TypeError: 'MyTypedObject' object attribute 'start_time' must be of type 'time'
>>> my_typed_object.start_time = datetime.time(13, 45)

これを行うより良い方法はありますか?しばらく Python を使ってきたので、車輪の再発明をしているような気がします。

4

2 に答える 2

1

なぜこれを行う必要があると感じるのかを自問する必要があります。それは確かにあまり Pythonic ではありません。通常、Python では、属性が特定の型を持つことを要求しません。代わりに、期待される型を文書化し、実際のパラメーターがすべて準拠していると想定します。これは、同じメソッドを実装するまったく無関係な型を意味する可能性があることに注意してください。たとえば、リストまたはタプルから継承することを特に要求せずに、パラメーターが反復可能であると期待する場合があります。

于 2012-11-19T15:06:19.833 に答える
1

あなたが探しているものをすでに実装している (そして他の多くの機能を提供している) ライブラリはEnthought Traitsです。

于 2012-11-21T13:11:12.133 に答える