2

そして、最良の方法として、Python 的に、そして可能な限り少ないコード行でという意味です。

私はPythonで属性を持つクラスを定義することに慣れています。

class MyClass(object):

    def __init__(self):
        self.value = 5

self.valueただし、が特定の型の値しかとらないようにしなければならないことがよくあります。過去に(PHP OOPのバックグラウンドから来ました)、これに似たgetter-setterメソッドでこれを行いました:

    def value(self, new_value = -1)
        if new_value == -1:
            return self.value
        if isinstance(new_value, int) and new_value > -1:
            self.value = new_value
        else:
            raise TypeError

次に でアクセスself.valueself.value()、 で設定しself.value(67)ます。通常、直接アクセスできないself.valueように名前を変更します。self.__value

最近、記述子を発見しました (または発見中です)。ここでの優れた議論に密接に従って、私は次のようなものを書きました:

class ValidatedAttribute(object):

    def __init__(self, key, kind):
        self.key = key
        self.kind = kind

    def __get__(self, instance, owner):
        if self.key not in instance.__dict__:
            raise AttributeError, self.key
        return instance.__dict__[self.key]

    def __set__(self, instance, value):
        if not isinstance(value, self.kind):
            raise TypeError, self.kind
        instance.__dict__[self.key] = value     


class MyUsefulClass(object):

    a = ValidatedAttribute("a", int)

しかし、いくつか質問があります!

まず、正確にはMyUsefulClass().a何ですか?クラスのインスタンスに何らかの形でバインドされた ValidatedAttribute クラスのインスタンスMyUsefulClassですか?

第二に、私が本当に欲しいのは、次のようなものです。

class MyUsefulClass(object):

    def __init__(self):
        self.value = Checker(int, 99)

    def Checker(self, kind, default):
        # Code for verifying that associated attribute is of type kind.

そして、他の記述子クラス全体を使用することなく、属性アクセスをある種のインターセプトメソッドにバインドします。

私の理解が不足していたら申し訳ありません - 私はまだ新しいスタイルの Python クラスに取り組んでいます。正しい方向への助けや指針をいただければ幸いです。

4

5 に答える 5

1

まず、MyUsefulClass().a とは正確には何ですか? MyUsefulClass クラスのインスタンスに何らかの形でバインドされた ValidatedAttribute クラスのインスタンスですか?

はい、まさにそれです。

そして第二に、私が本当に望んでいるのは [...] のようなもので、他の記述子クラス全体を使用することなく、何らかの方法で属性アクセスを何らかのインターセプト メソッドにバインドします。

すべての__getattribute__属性ルックアップを傍受するため、 を上書きすることもできますが、記述子を使用するよりもはるかに複雑です。

記述子は、まさにあなたがやりたいことのために機能します (自動検証)。唯一の改善点は、メタクラスを使用して自動的にキーを設定することです。クラス コードは次のようになります。

class MyUsefulClass(object):

    a = ValidatedAttribute(int)

ただし、最初に記述子に慣れてください。メタクラスは複雑で、理解するのが難しい場合があります。

ああ、そして私があなたに加える小さな変更が1つありますValidatedAttribute

def __init__(self, key, default):

    self.key = key
    self.kind = type(default)
    self.default = default

def __get__(self, instance, owner):
    if self.key not in instance.__dict__:
        return self.default
    return instance.__dict__[self.key]
于 2013-09-20T15:24:56.810 に答える
1

このようなことを自分で書く代わりに、traits ライブラリを使用してください: https://pypi.python.org/pypi/traits。ライブラリを使用することは、ほとんどの問題に対する Pythonic アプローチです。

ただし、一般的には、この種のチェックがほとんど不要なほど汎用的なコードを作成する必要があります。Pythonで簡単にできます。

于 2013-09-20T19:10:52.870 に答える
1

どうぞ、どうぞ、しないでくださいisinstance(new_value, int)

あなたはおそらく逃げるかもしれません

from numbers import Integral
isinstance(new_value, Integral)

しかし、アヒルのタイピングは完全に忌み嫌われています。

まず、MyUsefulClass().a とは正確には何ですか? MyUsefulClass クラスのインスタンスに何らかの形でバインドされた ValidatedAttribute クラスのインスタンスですか?

を見つけるためにMyUsefulClass().a、Python はクラスに問い合わせます。このクラスは、属性の getter-setter があることを伝え、Python に属性を尋ねるように指示します。属性はそれを見つけると言い、それから属性が何であるかをクラスに伝えます。属性はゲッターセッターではありません。

MyUsefulClass.aは getter-setter (プロパティ) であり、 ではありませんMyUsefulClass().a

そして第二に、私が本当に欲しいのは[もの]のようなものです

知る限り、インスタンスではなくクラスにのみプロパティを設定できます。プロパティを取得するか、プロパティがシャドウするアイテムを取得するかをどのように知るのでしょうか?

于 2013-09-20T15:21:56.057 に答える