6

クラスでプロパティ デコレータを使用しようとしています。それ自体はうまく機能しますが、にアクセスする必要があるコードは使用できませんREQUEST

class SomeClass():
   #Zope magic code
   _properties=({'id':'someValue', 'type':'ustring', 'mode':'r'},)

  def get_someValue(self):
    return self.REQUEST

  @property
  def someValue(self):
    return self.REQUEST

呼び出すget_someValueと目的の結果が得られますが、アクセスしようとするsomeValueAttributeError.

この動作の背後にあるロジックは何ですか? この制限を回避する方法はありますか?

(Zope 2.13.16、Python 2.7.3 を使用しています)

4

2 に答える 2

7

propertyデコレーターは、新しいスタイルのクラスでのみ機能します。つまり、 を継承するクラスですobject。一方、取得(属性アクセスを介してグローバルREQUESTオブジェクトにアクセスできます)は非常に「古い」pythonであり、オブジェクトを取得するために必要な取得ラッパーをproperty 無視するため、2つはうまく連携しません。REQUEST

Zope には独自の のpropertyようなメソッドがあり、これは新しいスタイルのクラスよりも前のものであり、実際にはデコレータと新しいスタイルのクラスより何年も前のpropertyと呼ばれるデコレータです。ただし、ラップされた関数は、ラップされたオブジェクトでどのように動作するかを知っています。ComputedAttributepropertyComputedAttributeAcquisition

デコレータComputedAttibuteと同じように使用できます。property

from ComputedAttribute import ComputedAttribute

class SomeClass():   
    @ComputedAttribute
    def someProperty(self):
        return 'somevalue'

ラッパー関数はComputedAttribute、取得ラッパーを扱うときに必要なラッピングのレベルで構成することもできます。ComputedAttributeその場合、 をデコレータとして使用することはできません。

class SomeClass():   
    def someValue(self):
        return self.REQUEST
    someValue = ComputedAttribute(someValue, 1)

ただし、装飾を行う新しい関数を定義するのは簡単です。

from ComputedAttribute import ComputedAttribute

def computed_attribute_decorator(level=0):
    def computed_attribute_wrapper(func):
        return ComputedAttribute(func, level)
    return computed_attribute_wrapper

これをユーティリティ モジュールのどこかに貼り付けます。その後、呼び出し可能なデコレータとして使用して、何かを Acquisition-aware プロパティとしてマークすることができます。

class SomeClass(): 
    @computed_attribute_decorator(level=1)
    def someValue(self):
        return self.REQUEST

とは異なりpropertyComputedAttributegetter にのみ使用できることに注意してください。セッターまたはデリーターはサポートされていません。

于 2012-09-22T15:52:35.540 に答える
3

必要な取得を回避したいが、クラスのコンストラクターで呼び出しコードからのリクエストを明示的に設定できない場合は、zope.globalrequest を使用してください。それ以外の場合は、ブラウザー ビューを検討することをお勧めします (これは、常にいくつかのコンテキストと要求をマルチ適応させます)。

于 2012-09-22T21:10:12.117 に答える