質問

私は定義しました Vector 3つのプロパティ変数があるクラス: x, yz. 。座標は実数である必要がありますが、次のことをすることを止めるものは何もありません。

>>> v = Vector(8, 7.3, -1)
>>> v.x = "foo"
>>> v.x
"foo"

このような「タイプ安全」を実装できます。

import numbers

class Vector:
    def __init__(self, x, y, z):
        self.setposition(x, y, z)

    def setposition(self, x, y, z):
        for i in (x, y, z):
            if not isinstance(i, numbers.Real):
                raise TypeError("Real coordinates only")

        self.__x = x
        self.__y = y
        self.__z = z

    @property
    def x(self):
        return self.__x

    @property
    def y(self):
        return self.__y

    @property
    def z(self):
        return self.__z

...しかし、それは非パイソンのようです。

提案?

役に立ちましたか?

解決

これらの値の設定でタイプをテストする理由を自問する必要があります。 aを上げるだけです TypeError 間違ったことにつまずくことがある計算で 価値 タイプ。ボーナス:標準操作はすでにこれを行っています。

>>> 3.0 / 'abc'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: unsupported operand type(s) for /: 'float' and 'str'

他のヒント

ダックタイピング Pythonの通常の方法です。それは何でも動作するはずです 振る舞います 数字のように、しかし必ずしもそうではありません 実数。

ほとんどの場合、Pythonでは、タイプを明示的に確認しないでください。コードが正しく動作する限り、コードをカスタムデータ型で使用できるため、柔軟性が得られます。

他の答えは、ここでタイプをチェックするのはあまり意味がないとすでに指摘しました。さらに、純粋なPythonで書かれている場合、クラスはそれほど速くはありません。

より多くのPythonicソリューションが必要な場合 - 次のようなプロパティセッターを使用できます。

@x.setter
def x(self, value):
    assert isinstance(value, numbers.Real)
    self.__x = value

アサートステートメントは、デバッグを無効にしたり、最適化モードを有効にしたりすると削除されます。

あるいは、強制することができます value セッターに浮かぶポイントに。タイプ/値がコンバーチブルでない場合、それは例外を引き起こします。

@x.setter
def x(self, value):
    self.__x = float(value)

しかし、次のことをするのを止めるものは何もありません:

誰かがそのようなことをするのを止めようとすることは、非パイソン語であると信じています。必要な場合は、タイプの安全性を確認する必要があります その間 使用する可能性のある操作 Vector, 、 私の意見では。

GVRを引用するには:

私たちは皆大人です。

結局。これを参照してください 質問 そして、詳細についてはその回答。

ここでより経験豊富なPythonistasがより良い答えを与えることができると確信しています。

このようにタイプの安全性を提供することは想定されていません。はい、誰かがあなたのコンテナが機能しない値を提供することにより、意図的にあなたのコードを破ることができます - しかし、これは他の言語でも同じです。そして、誰かがパラメーターの適切な値をメソッドまたはメンバー関数に入れたとしても、必ずしもそれが壊れていないことを意味するわけではありません:プログラムがIPアドレスを期待しているがホスト名を渡す場合、それはまだ機能しませんが、両方とも文字列。

私が言っているのは、Pythonの考え方は本質的に異なっています。ダックタイピングは基本的に次のように述べています:ねえ、私は特定のタイプではなく、インターフェイス、またはオブジェクトの動作に限定されます。オブジェクトが私が期待する種類のオブジェクトのように動作する場合、私は気にしません - ただそれを求めてください。

タイプチェックを導入しようとすると、基本的に言語の最も有用な機能の1つを制限しています。

そうは言っても、テスト駆動型開発、または少なくとも単体テストに入る必要があります。ダイナミック言語でそれを行わないという言い訳はありません - それは、コンパイル時間から1日に複数回テストスイートの実行に離れて、ビルドプロセスの別のステップまで(タイプ)エラーを移動するだけです。これは追加の労力のように思えますが、コードのエラーを検出するための本質的に強力な方法であるため、コードのデバッグと修正に費やされる時間を実際に削減します。

しかし、それで十分ですが、私はすでにとりとめのないものです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top