2014-02-14 64 views
0

我试图找出如何链类的方法来提高一个工具类我已经写 - 的原因,我不希望进入:)Python的描述符链方法

现在假设我想链上的一个类实例链类方法(在这种情况下,如何设置光标),例如:

# initialize the class instance 
db = CRUD(table='users', public_fields=['name', 'username', 'email']) 

#the desired interface class_instance.cursor(<cursor>).method(...) 
with sql.read_pool.cursor() as c: 
    db.cursor(c).get(target='username', where="omarlittle") 

是交代不清的是,我宁愿光标不坚持作为类属性的部分.get(...)后就一直称为并已返回,我想要求首先调用.cursor(cursor)

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

    def fields(self): 
     return ', '.join([f for f in self.public_fields]) 

    def get(self, target, where): 
     #this is strictly for illustration purposes, I realize all 
     #the vulnerabilities this leaves me exposed to. 
     query = "SELECT {fields} FROM {table} WHERE {target} = {where}" 
     query.format(fields=self.fields, table=self.table, target=target, 
        where=where) 
     self.cursor.execute(query) 

    def cursor(self, cursor): 
     pass # this is where I get lost. 
+0

为什么被标记为“元编程”,为什么标题中的“描述符”?在你的问题或任何可能的答案中,似乎没有任何元编程技术或描述符的用法...... – abarnert

回答

0

如果我理解你的要求,你要的是为cursor方法与get方法,希望工作返回一些对象。它没有理由返回的对象必须是self;它可以返回某个游标类型的实例。

该实例可以对self进行反向引用,也可以获得自己需要的任何内部副本作为游标,或者它可以是来自低级别数据库库的底层对象的包装,知道如何成为一个游标。

如果你看一下DB API 2.0规范,或像STDLIB的sqlite3它的实现,这也正是他们是如何做到这一点:一个DatabaseConnection对象(你从顶层connect功能得到的东西)具有cursor方法返回一个Cursor对象,而该Cursor对象具有execute方法。

所以:

class CRUDCursor(object): 
    def __init__(self, c, crud): 
     self.crud = crud 
     self.cursor = however_you_get_an_actual_sql_cursor(c) 

    def get(self, target, where): 
     #this is strictly for illustration purposes, I realize all 
     #the vulnerabilities this leaves me exposed to. 
     query = "SELECT {fields} FROM {table} WHERE {target} = {where}" 
     query.format(fields=self.crud.fields, table=self.crud.table, 
        target=target, where=where) 
     self.cursor.execute(query) 
     # you may want this to return something as well? 

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

    def fields(self): 
     return ', '.join([f for f in self.public_fields]) 

    # no get method 

    def cursor(self, cursor): 
     return CRUDCursor(self, cursor) 

然而,似乎仍然是你的榜样的主要问题。通常,在游标上执行SELECT语句后,您想从该游标读取行。您不会将光标对象保留在“用户”代码中,并且您明确不希望CRUD对象保持其光标,所以......您如何期望这样做?也许get应该在末尾return self.cursor.fetch_all()什么?

+0

我不想陷入为什么在构造函数中定义游标的细节中陷入困境, t为我们的架构工作,长话短说,它不会很好地与我们的自定义sql上下文管理器。 – NFicano

+0

@NFicano:我不是在'CRUD'类的构造函数中定义游标,而是在'CRUD.cursor'方法中定义游标,这正是您希望它发生的地方。关键是,无论需要什么状态,都将存储在新的'CRUDCursor'对象中,而不是存储在'CRUD'对象中,以便在调用'cursor'后不会保存在'CRUD'对象中,这是正是你所要求的。 – abarnert