簡體   English   中英

Python:類內的復合函數

[英]Python: Compound functions inside class

我正在嘗試在Django中復制類似於模型查詢的內容。

# database.py

class ModelFactory(object):
    def __init__(self, table):
        self.table = table

    def fields(self, *args):
        str_columns = ''
        for count, arg in enumerate(args):
            if count == 0:
                str_columns += arg
            else:
                str_columns += ', %s' % arg
        self.str_columns = str_columns

    def wheres(self, **kwargs):
        str_wheres = ''
        for count, (key, value) in enumerate(kwargs.items()):
            if count == 0:
                str_wheres += 'WHERE %s = %s' % (key, value)
            else:
                str_wheres += ' AND %s = %s' % (key, value)
        self.str_wheres = str_wheres

我的想法是按如下方式使用它:

from database import ModelFactory

myInstance = ModelFactory('myTable')
myQuery = myInstance.fields('column1', 'column2').wheres(column1 = 5)

我不確定我是否需要在ModelFactory類中使用新的類或函數來從“字段”和“位置”獲取結果以編譯SQL字符串進行查詢? 像下面這樣:

cur.execute('SELECT column1, column2 from myTable WHERE column1 = 5')

我也不確定調用class.function1.function2是否正確? Django帶有“對象”一詞,例如Instance.objects.filter()。exclude()

我試圖更改代碼庫,如下所示:

# database.py

class ModelFactory(object):
    def __init__(self, table):
        self.table = table

    def objects(self):
        def fields(self, **kwargs):
            return self.f(**kwargs)
        def wheres(self, *args):
            return self.w(*args)

    def f(self, *args):
        str_columns = ''
        for count, arg in enumerate(args):
            if count == 0:
                str_columns += arg
            else:
                str_columns += ', %s' % arg
        self.str_columns = str_columns

    def w(self, **kwargs):
        str_wheres = ''
        for count, (key, value) in enumerate(kwargs.items()):
            if count == 0:
                str_wheres += 'WHERE %s = %s' % (key, value)
            else:
                str_wheres += ' AND %s = %s' % (key, value)
        self.str_wheres = str_wheres

但是當我嘗試以下操作時:

from database import ModelFactory

myInstance = ModelFactory('myTable')
myQuery = myInstance.objects.fields('column1', 'column2').wheres(column1 = 5)

我收到AttributeError:“函數”對象沒有屬性“字段”

如果要鏈接對象的方法調用,則需要從方法中返回該對象。 即將return self添加到您的方法中。

因此,您的類聲明可能應該類似於以下內容:

class ModelFactory(object):
    def __init__(self, table):
        self.table = table

    def fields(self, *args):
        self.str_columns = ', '.join(args)
        return self

    def wheres(self, **kwargs):
        str_wheres = ' AND '.join('{} = {}'.format(k, v) for k, v in kwargs.items())
        self.str_wheres = 'WHERE {}'.format(str_wheres)
        return self

    def execute(self):
        // ATTN! This code is prone to SQL injection. Do not use!
        cur.execute('SELECT {columns} FROM {table} {wheres}'.format(columns=self.str_columns, table=self.table, wheres=self.wheres))

問題是您仍然具有objects作為函數:

def objects(self):

當前,這意味着您需要將其作為一個函數來調用myQuery行需要類似於以下內容:

myQuery = myInstance.objects().fields(...

然而,仍然是不夠的,因為fieldswheres都只有內范圍的objects功能。

如果要下推此路線,則需要創建一個在模型中的屬性objects下實例化的類QuerySet為此使用QuerySet 如果您查看源代碼,您將看到使像objects這樣的“簡單” objects工作需要多少魔法。

那么簡單的替代方法?

你將不得不作出類似的一類新QuerySet ,可以提供fieldswheres可鏈接的功能-讓我們把它WernerfeuerSet

class WernerfeuerSet:
    def __init__(self, table):
        self.table = table
    def fields(self, **kwargs):
        pass
    def wheres(self, **kwargs):
        pass

現在,在您的ModelFactory實例化它,類似:

class ModelFactory:
    def __init__(self, table):
        self.objects = WernerfeuerSet(table)

現在,您可以進行原始查詢,因為objectsModelFactory的屬性,而不是函數:

myQuery = myInstance.objects.fields('column1', 'column2').wheres(column1 = 5)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM