0

クラスのコンストラクターでプロパティを宣言したいと思います。

クラスMaterialOneは、私が現在どのようにそれを持っているかを示しています。すべてのプロパティは個別に定義する必要があります。ただし、同じfset / fget/fdelを指定したい類似のプロパティのグループがあります。

すべてのプロパティを明示的に記述するには多くのコードが必要になるため、より簡潔な方法でプロパティを定義したいと思います。したがって、コンストラクターにこれを処理させることを考えました。Class MateralTwoは、私がそれをどのように念頭に置いているかを示しています。

TypeErrorsが発生するため、残念ながら機能しません。

TypeError: get_property() takes exactly 1 argument (2 given)

なぜ文句を言うのかは理解できますが、解決策は思いつきません。コンストラクターのリストからプロパティを定義する必要は必ずしもありません。私が探しているのは、それらを定義するためのより簡潔でクリーンな方法です。

class MaterialOne(object):
    def __init__(self):
        pass;

    def del_property(attr):
        """Abstract deller"""
        def del_attr(self):
            setattr(self, attr, None);
        return del_attr

    def set_property(attr):
        """Abstract setter."""
        def set_attr(self, x):
            setattr(self, attr, x);            
        return set_attr

    def get_property(attr):
        """Abstract getter"""
        def get_attr(self):
            if getattr(self, attr) is not None:
                return getattr(self, attr); 
            else:
                return 'Some calculated value..'
        return get_attr

    _young = None;
    _shear = None;
    _poisson = None;

    young = property(fget=get_property('_young'), fset=set_property('_young'), fdel=del_property('_young'));
    shear = property(fget=get_property('_shear'), fset=set_property('_shear'), fdel=del_property('_shear'));
    poisson = property(fget=get_property('_poisson'), fset=set_property('_poisson'), fdel=del_property('_poisson'));


class MaterialTwo(object):
    def __init__(self):
        properties = ['young', 'shear', 'poisson'];
        self.create_properties(properties)

    def del_property(attr):
        """Abstract deller"""
        def del_attr(self):
            setattr(self, attr, None);
        return del_attr

    def set_property(attr):
        """Abstract setter."""
        def set_attr(self, x):
            setattr(self, attr, x);            
        return set_attr

    def get_property(attr):
        """Abstract getter"""
        def get_attr(self):
            if getattr(self, attr) is not None:
                return getattr(self, attr); 
            else:
                return 'Some calculated value..'
        return get_attr        

    def create_properties(self, items):
        for item in items:
            storage = '_'+item;
            setattr(self, storage, None);
            setattr(self, item, property(fget=self.get_property(storage), fset=self.set_property(storage), fdel=self.del_property(storage)));


steel = MaterialOne(); 
steel.young = 2e11;
steel.poisson = 0.3;
print steel.poisson
print steel.shear

carbon = MaterialTwo();
carbon.young = 2e11;
carbon.poisson = 0.3;
print carbon.poisson
print carbon.shear

コードについてもう少し明確にするため。私が書きたいのは、材料のクラス、固体、液体、気体であり、それぞれが材料のサブクラスです。多くの材料特性が割り当てられます。定義されているものに基づいて計算できるものもあります。たとえば、2つの弾性係数が与えられると、3分の1を計算できます。

これは、MaterialOneと非常によく似たものを使用して実装しました。しかし、私はより多くの材料特性を取得し、これらの種類の計算もより多く含めるようになるので、よりクリーンで整理されたものにしたいと思います。MaterialTwoで書いたように書くことは、私にとって可能性です。

4

3 に答える 3

1
setattr(self, item, property(...

これは最終的にあなたの問題です。プロパティは記述子であるため、インスタンスではなくクラスにバインドする必要があります。、、をオーバーライドして__getattr__()__setattr__()__delattr__()そこに実装する必要があります。

于 2013-01-04T22:54:18.463 に答える
0

すべての定義はself最初の引数として持つ必要があります。

これらの関数は次のようになります。

def del_property(self, attr):
def sel_property(self, attr):
def get_property(self, attr):
于 2013-01-04T22:48:10.663 に答える
-1

Pythonのオブジェクトでメソッドが呼び出されると、オブジェクトは最初の引数としてサイレントに渡されます。そのため、渡す引数が多すぎるというエラーが発生します。他の人が言ったように、あなたはあなたの関数への最初のパラメータとして自己を含める必要があります。

于 2013-01-04T22:52:03.660 に答える