Мне очень интересно, как SQLAlchemy строит строки запросов, например:
(Session.query(model.User)
.filter(model.User.age > 18)
.order_by(model.User.age)
.all())
Насколько я могу видеть, там применен какой-то Прокси-шаблон .В моем небольшом проекте мне нужно сделать похожую струнную конструкцию, используя подход ООП.Итак, я попытался восстановить это поведение.
Во-первых, какой-то объект, один из множества похожих объектов:
class SomeObject(object):
items = None
def __init__(self):
self.items = []
def __call__(self):
return ' '.join(self.items) if self.items is not None else ''
def a(self):
self.items.append('a')
return self
def b(self):
self.items.append('b')
return self
Все методы этого объекта возвращают self поэтому я могу вызывать их в любом порядке и неограниченное количество раз.
Во-вторых, прокси-объект, который будет вызывать методы субъекта, если это не метод execute , который вызывает объект для просмотрарезультирующая строка.
import operator
class Proxy(object):
def __init__(self, some_object):
self.some_object = some_object
def __getattr__(self, name):
self.method = operator.methodcaller(name)
return self
def __call__(self, *args, **kw):
self.some_object = self.method(self.some_object, *args, **kw)
return self
def perform(self):
return self.some_object()
И наконец:
>>> obj = SomeObject()
>>> p = Proxy(obj)
>>> print p.a().a().b().perform()
a a b
Что вы можете сказать об этой реализации?Есть ли лучшие способы создать желаемое количество классов, которые бы создавали такую строку с с тем же синтаксисом ?
PS: Извините за мой английский, это не мой основной язык.