簡體   English   中英

對非類屬性使用 Python 的 __get__ 描述符

[英]Using Python's __get__ descriptor for non-class attributes

使用__get__描述符我想實現這樣的目標:

class Wrapper:
    def __init__(self, wrapped_value):
        self._wrapped_value = wrapped_value

    def __get__(self, instance, owner):
        return self._wrapped_value

wrapper = Wrapper('foo')
assert type(wrapper) == type('foo')

事實證明,只有當Wrapper實例是某個其他類的類屬性時,才會調用__get__描述符,當Wrapper實例是獨立對象(未綁定到任何類屬性)時,它不會被調用。

有沒有辦法讓__get__描述符在非類屬性中工作?

主要目標是實現包裝器,當使用它時就像它包裝的值一樣(我知道乍一看這聽起來沒什么用,但在某些用例中這會有所幫助)。 那么也許有其他方法可以在不使用__get__描述符的情況下實現這一__get__

如果您希望您的 Wrapper 類控制對包裝類屬性的訪問,您可以使用__getattr__魔術方法。

假設我們有一個類Foo

class Foo(object):

    def bar(self):
        return 'bar'

    def baz(self):
        return 'baz'

假設我們正在與一些我們無法控制的代碼進行交互,這些代碼要求Foo.bar()的輸出為大寫,並且我們不想在我們的代碼中顯式調用.upper()

我們可以創建一個包裝類來攔截對Foo.bar()調用,但透明地允許訪問Foo的其他方法(這本質上是適配器模式)。

class Wrapper(object):

    def __init__(self, wrapped):
        self._wrapped = wrapped

    def __getattr__(self, name):
        # If 'name' isn't an attribute of this class,
        # get it from the wrapped instance.
        return getattr(self._wrapped, name)

    def bar(self):
        # Intercept calls to the wrapped instance's bar() method.
        return self._wrapped.bar().upper()



>>> wrapper = Wrapper(Foo())
>>> print wrapper.baz()
baz
>>> print wrapper.bar()
BAR

這個 Wrapper 類不會被typeisinstance檢查報告為Foo ,但否則它可以代替Foo ,只要調用代碼依賴於鴨子類型而不是(非pythonic)顯式類型檢查。

攔截諸如__str__魔術方法必須顯式完成。 這是因為這些方法總是直接在實例的類上查找,所以__getattr____getattribute__被繞過。

因此,要覆蓋Foo.__str__您需要執行以下操作:

class Foo(object):

    ...

    def __str__(self):
        return 'I am a Foo'


class Wrapper(object):

    ...

    def __str__(self):
        return str(self._wrapped)

>>> wrapper = Wrapper(Foo())
>>> print wrapper
I am a Foo

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM