[英]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(...
然而,仍然是不夠的,因為fields
和wheres
都只有內范圍的objects
功能。
如果要下推此路線,則需要創建一個在模型中的屬性objects
下實例化的類QuerySet
為此使用QuerySet
。 如果您查看源代碼,您將看到使像objects
這樣的“簡單” objects
工作需要多少魔法。
那么簡單的替代方法?
你將不得不作出類似的一類新QuerySet
,可以提供fields
和wheres
可鏈接的功能-讓我們把它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)
現在,您可以進行原始查詢,因為objects
是ModelFactory
的屬性,而不是函數:
myQuery = myInstance.objects.fields('column1', 'column2').wheres(column1 = 5)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.