2009-08-03 10 views
5

を使用してプロパティを作成しますか?私はこのような何かを持っているラムダゲッターとセッター

name = property(lambda self: self.__name, lambda self, value: self.__name = self.process_value(value)) 

をコンパイラは私のsetter関数を好きではない:

私はこれを試してみました。

+0

「なめらか」とは何ですか? –

+0

恐らく「何か」。 – hughdbrown

+0

プロパティ定義をもっと不明瞭にしようとしているようです。簡単な関数をlambdaに置き換える点は何ですか? –

答えて

19

あなたの問題は、ラムダの本体が式でなければならず、代入が文(Pythonの強力で深い区別です)でなければならないということです。あなたがlambda Sを犯すことを主張した場合、あなたは多くのそのような例を満たすと回避策を紹介します(常にそこに1が通常だ、ではないが)、そのようなこの場合は、のように:

name = property(lambda self: self.__name, 
       lambda self, value: setattr(self, 
              '_X__name', 
              self.process_value(value))) 

すなわち(ビルトインsetattrを使用(これは関数なので、lambdaの身体で受け入れ可能ではなく)代入(これはステートメントであり、従ってlambdaの身体では容認できません)。

編集は:(あなたはクラスXにいるよう_X__name__nameを変更)あなたは手動でもデュアル下線属性の名前マングリングを実行する必要がある属性名は引用符で囲まれた文字列として提示され、それとしてPyhonコンパイラは文字列リテラルではなく、適切な識別子について問題のmanglingを行うだけなので、setattrになければなりません。

+0

素晴らしい!ありがとう、アレックス。 – zinovii

+0

もう一つの問題があります。 setattrは "_name"ではなく "_name"に対してのみ機能します。 – zinovii

+0

ああ、手動でマングリングを実行する必要があります。それは引用符で囲まれた文字列です。 –

1

あなたがlistを拡張している場合は、このように、__setitem__を使用することができます。

class Position(list): 
    def __init__(self,x=0, y=0, z=0): 
     super(Position, self).__init__((x,y,z)) 

    x = property(lambda self: self[0], 
       lambda self,value: self.__setitem__(0, value)) 
    y = property(lambda self: self[1], 
       lambda self,value: self.__setitem__(1, value)) 
    z = property(lambda self: self[2], 
       lambda self,value: self.__setitem__(2, value)) 
関連する問題