Cụ thể hơn, tôi muốn có thể hỗ trợ lambda: <some_or_other_setter>
, nhưng tôi muốn giữ mã rõ ràng và ngắn gọn. Tôi phải xác nhận giá trị, vì vậy tôi cần một setter của một số loại. Tôi cần phải sử dụng lambda vì tôi cần phải chuyển callbacks cho các sự kiện Tkinter. Tôi cũng cần có khả năng sửa đổi giá trị của thuộc tính bên ngoài một ràng buộc.Điều gì sẽ là cách nhiệt tình nhất để tạo ra một thuộc tính có thể được sử dụng trong một lambda?
Trong các ví dụ sau đây, giả sử rằng tiện ích nút có tên là spam_button
đã được khai báo trên toàn cầu. Ngoài ra giả sử rằng lớp học Eggs
sẽ có ít nhất 10 thuộc tính hơn là cần phải được truy cập theo cùng một cách (tôi thích tính nhất quán).
Cách thứ nhất có thể, tôi có thể làm điều này là sử dụng chỉ getter và 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
Nhưng nếu tôi sử dụng phương pháp này và có rất nhiều thuộc tính, các mã có thể có được nhiều thời gian để quản lý.
Cách thứ hai tôi có thể làm điều này là sử dụng tài sản, và sử dụng các setter trong callback:
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)
Bằng cách này là một chút đơn giản hơn là người đầu tiên khi truy cập vào thuộc tính trực tiếp, nhưng không phù hợp khi sử dụng lambda.
Cách thứ ba để làm điều này sẽ làm cho một lớp học bổ sung với get và thiết lập các phương pháp:
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'))
Phương pháp này là tổ chức hơn là người đầu tiên, nhưng tôi sẽ cần phải thực hiện một lớp đối với từng loại xác thực.
Cách cuối cùng tôi có thể làm điều đó là phương pháp sử dụng thay vì tài sản (bất động sản là những ví dụ thứ hai):
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
Phương pháp này có lẽ sẽ là ngắn nhất, nhưng nó là khó khăn hơn trong nháy mắt để trả lời liệu Tôi đang nhận hoặc thiết lập.
Phương pháp nào (nếu có) của những phương pháp này được ưu tiên?
Cảm ơn ý tưởng, nhưng tôi không thực sự muốn sử dụng chuỗi để truy cập thuộc tính (tôi cũng có thể sử dụng từ điển) và điều này không cung cấp cách để đặt và xác thực giá trị bên ngoài một ràng buộc (trừ khi tôi thực hiện 'self.set ('spam', 'Ouch', spam_condition)()' mỗi khi tôi muốn đặt giá trị, điều này thực sự xấu). Ngoài ra, bạn sẽ muốn thêm tham số 'event' vào hàm' setter', nếu không Tkinter không thể chuyển sự kiện (và nhận 'ValueError'). –
Bây giờ thiết lập có thể được sử dụng từ bất cứ nơi nào. – agf
Nếu tôi sử dụng 'lambda e: self.spam_setter()' làm gọi lại và loại bỏ tham số 'event' khỏi' setter', tôi không cần phải xác định 'val =' mỗi lần tôi đặt giá trị. Có thể loại bỏ 'e' khỏi' lambda e: 'trong hàm gọi lại không? –