python - タックス - syntaxerror: invalid syntax




クラス状態が無効な場合に発生するエラーは何ですか? (4)

Pythonクラスでは、そのメソッドを実行する前にクラスの他の属性の一部を変更する必要がある場合、インスタンスメソッドからどのようなエラーを発生させる必要がありますか?

私はInvalidOperationException 、 "メソッド呼び出しがオブジェクトの現在の状態に対して無効であるとスローされる例外"を使用するC#の背景から来ていますが、 Pythonで同等の組み込み例外を見つけることができませんでした。

私は、問題が関数のパラメータである場合、 ValueError (組み込みの演算または関数が正しい型を持つ引数を受け取ったときに発生し、不適切な値を受け取った場合)を発生させています。 これは、技術的にはselfパラメータにとって無効な値だと思います。 それはそれを扱う正しい方法ですか? たとえば、これは熟語です: raise ValueError("self.foo must be set before running self.bar()")


RuntimeErrorは、無効な状態を通知するための組み込み例外の中で最も適切なものです。

CPythonでどのように使用されているかのこの例を参照してください。

Python 2.7.10 (default, Jul 13 2015, 12:05:58)
[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from threading import Thread
>>> Thread().join()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 938, in join
    raise RuntimeError("cannot join thread before it is started")
RuntimeError: cannot join thread before it is started

CPythonの実装自体でさえ、ライブラリ間の特定の例外タイプの使用に関して一貫性がないことに注意することが重要です。 時にはValueErrorが代わりに使用されていますが、私の意見では、Pythonのドキュメントからその説明は、その使用が他の状況のた​​めに予約されていることを示しています。 RuntimeErrorはより一般的な例外であり、適切な入力が与えられていればコードが正常に動作しない場合に使用しなければなりません。これは、オブジェクトが無効な状態にある場合の状況と多少似ています。


ValueErrorはこの場合に発生させる最も良い方法です。 Pythonの場合は、 組み込みの例外タイプを独自のものに比べて使うほうがよいでしょう。 新しい例外型は、それをキャッチする必要があり、組み込み型をキャッチするときとはまったく異なる動作をすることが予想される場合にのみ作成してください。 この場合、状況は発生しないはずです。問題のクラスを使用する際にエラーが発生する可能性があるため、このキャッチを期待していません。 このためには、新しい型を作成して別の名前にする価値はありません。つまり、 ValueError()渡すメッセージ文字列が対象となります。

このような無効な状態が不可能になるようにクラスを再構成することは可能ですか?


私はpythonic方法は、メソッド呼び出しが誤った状態になっているにもかかわらずクラッシュしないような状態にオブジェクトを残していないと思う。 これらは最も難しいバグです。バグがどこで発生したのかは、プログラムが最後に転倒した場所ではありません。

例えば。

class PseudoTuple(object):
    """
The sum method of PseudoTuple will raise an AttributeError if either x or y have
not been set
"""
    def setX(self, x):
        self.x = x

    def setY(self, y):
        self.y = y

    def sum(self):
        """
In the documentation it should be made clear that x and y need to have been set
for sum to work properly
"""
        return self.x + self.y

class AnotherPseudoTuple(PseudoTuple):
     """
For AnotherPseudoTuple sum will now raise a TypeError if x and y have not been 
properly set
"""
    def __init__(self, x=None, y=None):   
        self.x = x
        self.y = y

やらなければならないことは何かのようなものです

class BadPseudoTuple(PseudoTuple):
    """
In BadPseudoTuple -1 is used to indicate an invalid state
"""
    def __init__(self, x=-1, y=-1):
        self.x = x
        self.y = y

    def sum(self):
        if self.x == -1 or self.y == -1:
            raise SomeException("BadPseudoTuple in invalid state")
        else:
            return self.x + self.y

私はこれが次のモットーの下にあると思う:

許可を得るよりも、許しを求める方が簡単です

例外状態が、クラスを悪用してユーザーエラーではなく通常の実行過程で発生すると予想されるものであれば、独自の例外を作成するのが妥当と思われます。 StopIterationとiteratorsがこれの例です。


私はあなたがやっているように、関数のパラメータに問題があるときはValueErrorを上げるべきだと思っています。問題が設定されなければならない属性を持っているときは、 AttributeErrorが発生します。

また、より具体的な例外を作成するためにAttributeErrorをサブクラス化することもできますが、必要ではありません。 エラーメッセージのAttributeError Exceptionは十分にクリアです。





exception