更具體地說,我希望能夠支持lambda: <some_or_other_setter>
,但我希望保持代碼清晰和簡潔。我必須驗證這個值,所以我需要一個類似的setter。我需要使用lambda,因爲我需要將回調傳遞給Tkinter事件。我還需要能夠修改綁定外的屬性值。什麼將是一個可以用在lambda中的屬性的最pythonic方法?
在我下面的例子中,假設名爲spam_button
的按鈕小部件已經在全局聲明。另外假設類將至少有10個屬性,而不需要全部以相同的方式訪問(我喜歡一致性)。
第一個可能的辦法,我能做到這一點是隻使用getter和setter方法:
class Eggs(object):
def __init__(self):
self._spam = ''
self.set_spam('Monster')
print self.get_spam()
spam_button.bind('<Enter>', lambda: self.set_spam('Ouch'))
def set_spam(self, spam):
if len(spam) <= 32:
self._spam = spam
def get_spam(self):
return self._spam
但是,如果我用這個方法,並有很多的屬性,代碼可能會太長管理。
我能做到這一點的第二種方法是使用性能,並在回調使用的setter:
class Eggs(object):
def __init__(self):
self._spam = ''
self.spam = 'Monster'
print self.spam
spam_button.bind('<Enter>', lambda: self.set_spam('Ouch'))
def set_spam(self, spam):
if len(spam) <= 32:
self._spam = spam
def get_spam(self):
return self._spam
spam = property(get_spam, set_spam)
直接訪問屬性時,此方法是比第一更簡單了一點,但不一致使用時拉姆達。
第三種方式做,這將是使用get和set方法的附加類:
class Spam(object):
def __init__(self):
self._value = ''
def set(self, value):
if len(spam) <= 32:
self._value = value
def get(self):
return self._value
class Eggs(object):
def __init__(self):
self._spam = ''
self.spam = Spam()
self.spam.set('Monster')
print self.spam.get()
spam_button.bind('<Enter>', lambda: self.spam.set('Ouch'))
這種方法比第一個更有組織,但我需要做一個類每類的驗證。
我可能會做最後的辦法是使用方法,而不是屬性(Properties是第二個例子):
class Eggs(object):
def __init__(self):
self._spam = ''
self.spam('Monster')
print self.spam()
spam_button.bind('<Enter>', lambda: self.spam('Ouch'))
def spam(self, spam=None):
if spam != None:
if len(spam) <= 32:
self._spam = spam
else:
return self._spam
這種方法將可能是最短的,但一看就知道是難我正在接受或設置。
哪些(如果有)這些方法是首選?
感謝您的想法,但我真的不想使用字符串來訪問屬性(我可能只是使用字典),並且這不提供一種方法來設置和驗證綁定外的值除非我每次想設置值self.set('spam','Ouch',spam_condition)()',這真的很難看)。另外,你需要爲'setter'函數添加一個'event'參數,否則Tkinter不能傳遞事件(並且會得到一個'ValueError')。 –
現在可以在任何地方使用setter。 – agf
如果我使用'lambda e:self.spam_setter()'作爲回調函數,並從'setter'中移除'event'參數,那麼每次設置該值時都不需要指定'val ='。是否有可能在回調中擺脫'lambda e:'的'e'? –