簡體   English   中英

以更短的方式定義setter

[英]Defining setter in a shorter way

目前,當我想定義一個setter並單獨留下getter時,我這樣做:

@property
def my_property(self):
    return self._my_property

@my_property.setter
def my_property(self, value):
    value.do_some_magic()
    self._my_property = value

有沒有辦法縮短它? 我想跳過這部分,因為它總是看起來一樣:

@property
def my_property(self):
    return self._my_property

沒有開箱即用的解決方案,但您可以嘗試這樣的事情:

def defprop(name):
    def getter(self):
        return getattr(self, name)
    return property(getter)

class C(object):
    # ...
    my_dictionary = defprop('_my_dictionary')
    # ...

但是,這並沒有為您節省許多擊鍵,您仍然需要復制屬性名稱。 除此之外,它不太明確。


更新 :經過一番思考后,我想出了這個基於描述符的hackish技巧(免責聲明:這只是為了演示,我並不暗示這是一個很好的做法,除非你有一個很好的理由這樣做) :

class with_default_getter(object):
    def __init__(self, func):
        self._attr_name = '_{0.__name__}'.format(func)
        self._setter = func

    def __get__(self, obj, type):
        return getattr(obj, self._attr_name)

    def __set__(self, obj, value):
        return self._setter(obj, value)

用法:

class C(object):
    @with_default_getter
    def my_property(self, value):
        print 'setting %s'
        self._my_property = value

>>> c = C()
>>> c.my_property = 123
setting 123
>>> c.my_property
123

這與@georg建議的幾乎相同,只是將實現展開到描述符。

您可以按照下划線約定制作一個自動創建getter的裝飾器:

def setter(fn):
    def _get(self):
        return getattr(self, '_' + fn.__name__)
    def _set(self, val):
        return fn(self, val)
    return property(_get, _set)

或者更簡潔,如果你更喜歡這種風格:

def setter(fn):
    return property(
        lambda self: getattr(self, '_' + fn.__name__),
        fn)

用法:

class X(object):
    @setter
    def my_property(self, value):
        self._my_property = value + 1

x = X()
x.my_property = 42
print x.my_property # 43

沒有我所知道的捷徑 - 記住顯式優於隱式(來自蟒蛇的禪)。

可能在你的代碼到目前為止,屬性總是那樣 - 但你可以在某個時候寫一個屬性getter來獲取一個完全計算的值 - 在這種情況下你的屬性getter和setter看起來根本就不會這樣。

如果你願意的話,你可以寫一個包裝器來提供那些簡單的默認方法作為包裝器的一部分。

def set_my_property(self, value):
    value.do_some_magic()
    self._my_property = value

my_property = property(fset=set_my_property)

暫無
暫無

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

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