如何进行function().function()?

Jak*_*ane 0 python python-2.7

我想调用这样的函数:

select().orderBy()首先select()被调用,然后orderBy()被调用.

为了实现它,我将一个方法定义为select方法,如下所示:

def select(self):
    if self.key is not None:
        self.request = """SELECT """ + self.key[0] + """ FROM """ + self.table
    else:
        self.request = """SELECT * FROM """ + self.table

    def where():
         self.request += """ WHERE """ + self.key[0] + """ = """ + self.value[0]
         return self.request
    def orderBy(key, value):
        self.request += """ ORDER BY """ + key + """ """ + value
        return self.request
    def groupBy(arg):
        self.request += """ GROUP BY """ + arg
        return self.request
    def limit(arg):
        self.request += """ LIMIT """ + arg
        return self.request
Run Code Online (Sandbox Code Playgroud)

但是我有这个错误消息:

AttributeError: 'NoneType' object has no attribute 'orderBy'
Run Code Online (Sandbox Code Playgroud)

有人知道该怎么办吗?

Mar*_*ers 5

链接方法(流畅或生成API)仅在前面的调用返回支持下一个方法的对象时才有效; in foo().bar(),foo()必须返回一个有.bar()方法的对象.您的.select()方法返回None一个不支持任何其他方法的对象.

你的select功能应该返回self:

return self
Run Code Online (Sandbox Code Playgroud)

呼叫是可链接的.您可能希望其他调用也返回self,而不是self.request.我在这里假设其他方法确实是同一个类的方法(你的例子是缺少self每个方法的参数).

如果你想拥有这些方法只能是因为你嵌套他们里面select()的方法,那么将无法工作在所有.这些函数对象只是函数体中未使用的本地名称,它们在返回的对象上不可用.

如果这些方法不应该存在于定义的同一个类中select,则定义一个类并让该类实现额外的方法.有select()返回类的一个实例:

class Selectable:
    # ...
    def select(self):
        column = '*' if new_clone.key is None else new_clone.key
        request = """SELECT {} FROM {}""".format(column, new_clone.table)
        return Query(request)

class Query:
    def __init__(self, request):
        self.request = request
    def where(self):
         self.request += """ WHERE """ + self.key[0] + """ = """ + self.value[0]
         return self
    def orderBy(self, key, value):
        self.request += """ ORDER BY """ + key + """ """ + value
        return self
    def groupBy(self, arg):
        self.request += """ GROUP BY """ + arg
        return self
    def limit(self, arg):
        self.request += """ LIMIT """ + arg
        return self
Run Code Online (Sandbox Code Playgroud)

注意Query()返回的每个方法self都可以继续链接.

但是,您正在操作同一个实例,并且无法从公共库创建单独的查询对象.SQLAlchemy做得更好; 它返回一个克隆self,与添加的变化:

def _clone(self):
    return type(self)(self.request)

def where(self):
    new_clone = self._clone()
    new_clone.request += """ WHERE {} = {}""".format(self.key[0], self.value[0])
    return new_clone
Run Code Online (Sandbox Code Playgroud)

现在,base = Selectable().select()filtered = base.where()创建filtered一个独特的克隆,以便您可以继续使用base来构建其他查询.

(在现实中,SQLAlchemy中使用装饰替换self新创建的克隆).