如何继续function()。function()?

2024-04-19 10:26:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望调用如下函数:

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

但我有个错误信息:

AttributeError: 'NoneType' object has no attribute 'orderBy'

有人知道怎么做吗?你知道吗


Tags: 方法key函数fromselfbyreturnvalue
1条回答
网友
1楼 · 发布于 2024-04-19 10:26:12

链接方法(一个流畅的或生成的API)只有在前面的调用返回一个支持下一个方法的对象时才起作用;在foo().bar()中,foo()必须返回一个具有.bar()方法的对象。您的.select()方法返回None,一个不支持任何其他方法的对象。你知道吗

你的select函数应该返回self

return self

使呼叫可以链接。您可能希望其他调用也返回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

注意,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

现在base = Selectable().select()filtered = base.where()使filtered成为一个不同的克隆,因此您可以继续使用base构建其他查询。你知道吗

(实际上,SQLAlchemy使用decoratorself替换为newly created clone)。你知道吗

相关问题 更多 >