Python: универсальные получатели и сеттеры

TL; DR: необходимо определить уникальный набор геттеров и сеттеров для каждого свойства () 'd переменной. Могу ли я определить общие геттеры и сеттеры и использовать их с любой переменной, которую я хочу?

Предположим, я создаю класс с хорошими геттерами и сеттерами:

class Foo def getter(self): return _bar+' sasquatch' def setter(self, value): _bar = value+' unicorns' bar = property(getter, setter) 

Довольно здорово, правда?

Теперь предположим, что я добавил другую переменную под названием «baz», и я не хочу, чтобы ее не оставляли без внимания это удовольствие от sasquatch / unicorn. Ну, я думаю, я мог бы сделать еще один набор геттеров и сеттеров:

 class Foo def bar_getter(self): return _bar+' sasquatch' def bar_setter(self, value): _bar = value+' unicorns' bar = property(bar_getter, bar_setter) def baz_getter(self): return _baz+' sasquatch' def baz_setter(self, value): _baz = value+' unicorns' baz = property(baz_getter, baz_setter) 

Но это не очень СУХОЙ и бесполезно загромождает мой код. Думаю, я мог бы сделать это немного DRYer:

 class Foo def unicornify(self, value): return value+' unicorns' def sasquatchify(self, value): return value+' sasquatch' def bar_getter(self): return self.sasquatchify(_bar) def bar_setter(self, value): _bar = self.unicornify(_bar) bar = property(bar_getter, bar_setter) def baz_getter(self): return self.sasquatchify(_baz) def baz_setter(self, value): _baz = self.unicornify(_baz) baz = property(baz_getter, baz_setter) 

Хотя это может сделать мой код DRYer, это не идеально. Если бы я хотел unicornify и sasquatchify еще две переменные, мне пришлось бы добавить еще четыре функции!

Должен быть лучший способ сделать это. Могу ли я использовать один общий приемник и / или сеттер для нескольких переменных?

Unicorn-less и безсмысленная реализация реального мира: я использую ORM SQLAlchemy и хочу преобразовать некоторые данные при их хранении и извлечении из базы данных. Некоторые из преобразований применимы к нескольким переменным, и я не хочу загромождать свои классы с помощью геттеров и сеттеров.

5 Solutions collect form web for “Python: универсальные получатели и сеттеры”

Как насчет просто:

 def sasquatchicorn(name): return property(lambda self: getattr(self, name) + ' sasquatch', lambda self, val: setattr(self, name, val + ' unicorns')) class Foo(object): bar = sasquatchicorn('_bar') baz = sasquatchicorn('_baz') 

Несколько более общий:

 def sasquatchify(val): return val + ' sasquatch' def unicornify(val): return val + ' unicorns' def getset(name, getting, setting): return property(lambda self: getting(getattr(self, name)), lambda self, val: setattr(self, name, setting(val))) class Foo(object): bar = getset('_bar', sasquatchify, unicornify) baz = getset('_baz', sasquatchify, unicornify) 

Или, с едва большей работой, вы можете использовать полный протокол дескриптора, как описано в ответе agf .

Для этого используется property протокола дескриптора :

 class Sasicorn(object): def __init__(self, attr): self.attr = "_" + attr def __get__(self, obj, objtype): return getattr(obj, self.attr) + ' sasquatch' def __set__(self, obj, value): setattr(obj, self.attr, value + ' unicorns') class Foo(object): def __init__(self, value = "bar"): self.bar = value self.baz = "baz" bar = Sasicorn('bar') baz = Sasicorn('baz') foo = Foo() foo2 = Foo('other') print foo.bar # prints bar unicorns sasquatch print foo.baz # prints baz unicorns sasquatch print foo2.bar # prints other unicorns sasquatch 

Хотя property фабричной функции может быть хорошо для вашего примера с игрушкой, это звучит, как будто вам нужно больше контроля для вашего реального использования.

Один из моих коллег предложил использовать закрытие, чтобы возвращать функции getter и setter, и это то, что я решил использовать.

 class Foo(object): def setter(var): def set(self, value): setattr(self, var, value+' unicorn') return set def getter(var): def get(self): return getattr(self, var)+' sasquatch' return get bar = property(getter('_bar'), setter('_bar')) f = Foo() f.foo = 'hi' print f.foo 

Но спасибо всем за ваши ответы 🙂

Используя getattribute и setattr, вы можете определить это для всех атрибутов прошлого и будущего.

 class Foo(object): x = 3 def __getattribute__(self, attr): return str(object.__getattribute__(self, attr)) + ' sasquatch' def __setattr__(self, attr, value): object.__setattr__(self, attr, str(value) + ' unicorn') print Foo.x f = Foo() print fx fy = 4 print fy 

Это печатает:

 3 3 sasquatch 4 unicorn sasquatch 
 # coding=utf-8 __author__ = 'Ahmed Şeref GÜNEYSU' class Student(object): def __init__(self, **kwargs): for k, v in kwargs.iteritems(): self.__setattr__(k, v) if __name__ == '__main__': o = Student(first_name='Ahmed Şeref', last_name='GÜNEYSU') print "{0} {1}".format(o.first_name, o.last_name) print o.email 

дает

 Ahmed Şeref GÜNEYSU File "/Users/ahmed/PycharmProjects/sanbox/abstract_classes/object_initializer/__init__.py", line 13, in <module> print o.email AttributeError: 'Student' object has no attribute 'email' Process finished with exit code 137 
  • множественный импорт python для общего модуля
  • как преобразовать эту строку даты в "2011-02-15T12: 00 + 00: 00" объект python datetime
  • Python: как найти значение в списке меньше целевого
  • Продолжить чтение файла с позиции, где он был оставлен
  • преобразование двоичной строки в float
  • проверка утверждений в лямбда в python
  • Как конвертировать DD в DMS в Python
  • Есть ли способ получить возвращаемое значение функции и проверить, что это «отличное от нуля» в одно и то же время?
  •  
    Interesting Posts for Van-Lav

    Python, передайте переменную по имени в поток

    Использование регулярного выражения для запятой выделяет большое количество в системе нумерации южной Азии

    Копирование содержимого файла в многомерный список в Python

    Plotly убил мою установку python

    Как я могу вернуть код статуса HTTP 204 из представления Django?

    Решение системы нелинейных уравнений с питоном

    Как сделать numba @jit использовать все ядра процессора (распараллелить numba @jit)

    Клиент javascript WebSocket и сервер python. Извлечение мусора на выходе

    Что такое :: (двойная двоеточие) в Python при подпиксельных последовательностях?

    Программирование на Python GPU

    Программа сохранения пользовательских баллов

    Python добавляет новый элемент в словарь

    Найти все подмножества из списка множеств, которые появляются, по крайней мере, в N разных наборах

    Ошибка открытия файла с помощью кодека utf-8 в python

    SQLAlchemy introspect тип столбца с наследованием

    Python - лучший язык программирования в мире.