Ответы пользователя по тегу Метапрограммирование
  • Python как создать метод для метода динамически?

    ckpunT
    @ckpunT Автор вопроса
    Немного развил свою мысль.
    def clause(func):
        def func_wrapper(*args, **kwargs):
            operation = " " + func.__name__.replace('_', '') + " "
            if args:
                if len(args) == 1:
                    a = operation + "".join(str(i) for i in args)
                else:
                    a = "(" + operation.join(str(i) for i in args) + ")"
            else:
                a = ""
            if kwargs:
                clause = []
                for k, v in kwargs.items():
                    op = '='
                    if str(v).find('%') >= 0:
                        op = 'like'
                    clause.append("%s %s '%s'" % (k, op, v))
                if len(kwargs) == 1:
                    k = operation + "".join(clause)
                else:
                    k = "(" + operation.join(clause) + ")"
            else:
                k = ""
            return a + k
        return func_wrapper
    
    class ORM():
        def __init__(self, table):
            self.table = table
        def select(self, *args):
            if args:
                list_cols = ", ".join(args)
            else:
                list_cols = "*"
            self.sql = "select %s from %s" % (list_cols, self.table)
            return self
        def insert(self, **kwargs):
            if not kwargs:
                raise
            else:
                col = ", ".join(kwargs.keys())
                val = ", ".join(["'{}'"] * len(kwargs))
                sql = "insert into %s (%s) values (%s)" % (self.table, col, val)
                self.sql = sql.format(*kwargs.values())
                return self
        def update(self, **kwargs):
            if not kwargs:
                raise
            else:
                upd = ", ".join(["%s='%s'" % (k, v) for k, v in kwargs.items()])
                self.sql = "update %s set %s" % (self.table, upd)
                return self
        def delete(self):
            self.sql = "delete from %s" % (self.table)
            return self
        def __getattr__(self, name):
            def wrap(*args, **kwargs):
                exp = " " + name.replace('_', ' ') + " "
                if args:
                    self.sql = self.sql + exp + ", ".join(str(i) for i in args)
                elif kwargs:
                    clause = []
                    for k, v in kwargs.items():
                        op = '='
                        if str(v).find('%') >= 0:
                            op = 'like'
                        clause.append("%s %s '%s'" % (k, op, v))
                    self.sql = self.sql + exp + " ".join(clause)
                return self
            return wrap
        def __repr__(self):
            s = self.sql[:]
            self.sql = ''
            return s
    
    
    @clause
    def _and(*args, **kwargs):
        pass
    
    @clause
    def _or(*args, **kwargs):
        pass
    
    def _in(**kwargs):
        for k, v in kwargs.items():
            return k + " in (" + ", ".join(str(i) for i in v) + ")"

    >>> t = ORM('test')
    >>> t.select('id', 'count(id) as cid', 'name', 'age').where(_or(_and(name='alex%', age=25), _and(name='%bob', age='27'), _in(age=range(25,35)))).group_by('cid', 'name', 'age').order_by('cid', 'name', 'age').limit(10)
    select id, count(id) as cid, name, age from test where ((age = '25' and name like 'alex%') or (age = '27' and name like '%bob') or age in (25, 26, 27, 28, 29, 30, 31, 32, 33, 34)) group by cid, name, age order by cid, name, age limit 10
    Ответ написан