Каким будет наиболее питонический способ создания атрибута, который можно использовать в лямбде?

В частности, я хочу иметь возможность поддерживать лямбда: , но я хочу, чтобы код был ясным и кратким. Мне нужно проверить значение, поэтому мне нужен какой-то сеттер. Мне нужно использовать лямбда, потому что мне нужно передавать обратные вызовы событиям Tkinter. Мне также нужно иметь возможность изменять значение атрибута вне привязки.

В моих следующих примерах предположим, что виджет кнопки с именем spam_button объявлен глобально. Также предположим, что класс Eggs будет иметь не менее 10 атрибутов, чем необходимо, чтобы все они были доступны одинаково (мне нравится согласованность).

Первый возможный способ сделать это - использовать только геттеры и сеттеры :

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

Но если я использую этот метод и у меня много атрибутов, код может стать слишком длинным для управления.

Второй способ, которым я мог бы это сделать, - это использовать свойства и использовать сеттер в обратном вызове:

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'))

Этот метод более организован, чем первый, но мне нужно будет создать класс для каждый тип проверки.

Последний способ, которым я мог бы это сделать, - это использовать методы вместо свойств (свойства были вторым примером):

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

Этот метод, вероятно, будет самым коротким, но с первого взгляда сложнее определить, Я получаю или устанавливаю.

Какой (если есть) из этих методов предпочтительнее?

5
задан agf 1 November 2011 в 18:40
поделиться