14

次のようなバグに時間をかけすぎました。

>>> class Odp():
    def __init__(self):
        self.foo = "bar"


>>> o = Odp()
>>> o.raw_foo = 3 # oops - meant o.foo

属性を持つクラスがあります。私はそれを設定しようとしていましたが、なぜ効果がないのだろうと思っていました。次に、元のクラス定義に戻ると、属性の名前が少し異なることがわかりました。したがって、意図したものではなく、新しい属性を作成/設定していました。

まず第一に、これはまさに静的型付け言語が防止するはずのエラーのタイプではないでしょうか? この場合、動的型付けの利点は何ですか?

第二に、 を定義するときにこれを禁止してOdp、トラブルを回避する方法はありますか?

4

1 に答える 1

22

目的のためにメソッドを実装できます。これは、目的のために誤用されることが多い__setattr__メソッドよりもはるかに堅牢です__slots__(たとえば、__slots__クラスが継承されると自動的に「失われ」ますが、__setattr__明示的にオーバーライドされない限り存続します)。

def __setattr__(self, name, value):
  if hasattr(self, name):
    object.__setattr__(self, name, value)
  else:
    raise TypeError('Cannot set name %r on object of type %s' % (
                    name, self.__class__.__name__))

たとえば、属性をクラス レベルで設定したり、属性を直接割り当てるのではなくメソッドで使用したりして、設定できるようにhasattrたい名前が成功することを確認する必要があります。(インスタンスではなくクラスに属性を設定することを禁止するには、同様の特別なメソッドでカスタム メタクラスを定義する必要があります)。object.__setattr____init__

于 2010-06-29T03:08:53.050 に答える