2

I want to make my own MagicCursor class. I want it to inherit all method and attributes from sqlite3.Cursor(). But it looks not that easy in t his case.

usually we create a cursor like this:

import sqlite3
conn = sqlite3.connect('test.db')
crs = conn.cursor()

because there's a connection in between. So I think I have to define my own Connection Class and then define my own Cursor.

Here's what I want to implement:

import sqlite3
conn = MyConnect('test.db') ## this returns me a connect object, inherit from         sqlite3.Connection 
crs = conn.cursor() ## this returns me a MyCursor class,
                ## which inherit from sqlite3.Cursor() and has my customized method

Here's my code, but failed.

class MyConnect(sqlite3.Connection):
    def cursor(self):
        return MyCursor(self)

class MyCursor(sqlite3.cursor):
    def __init__(self, connect):
        self = connect.cursor()

    def mymethod1(self, argv)
         ...... return ...... ## what ever I defined

Anyone got an idea how to implement that?

MacSanhe
  • 2,212
  • 6
  • 24
  • 32
  • I do not believe you want to reassign `self` like you do in your `__init__` method. Shouldn't that be `sqlite3.cursor.__init__(self)` (or something close)? Sqlite3 is a compiled extension on my system - you'd have to look up the call signature and see how (or if) it supports a connection parameter. You may not be able to go about adding a method to a compiled extension in this way. – g.d.d.c May 15 '14 at 16:41

1 Answers1

5
import sqlite3
class MyConnect(sqlite3.Connection):
    def cursor(self):
        return super(MyConnect, self).cursor(MyCursor)

class MyCursor(sqlite3.Cursor):
    def mymethod1(self, argv):
        print('Got here')

conn = sqlite3.connect(':memory:', factory=MyConnect)
print(conn)
# <__main__.MyConnect object at 0x90db66c>

cursor = conn.cursor()
print(cursor)
# <__main__.MyCursor object at 0x90d19dc>

cursor.mymethod1('foo')
# Got here

In this example, super(MyConnect, self).cursor(MyCursor) calls sqlite3.Connection.cursor(MyCursor).

sqlite3.Connection.cursor accepts an optional argument, cursorClass. When supplied, that is the class used to instantiate the cursor.

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • It works!! Thank you!! Could you tell me how could this works? – MacSanhe May 15 '14 at 16:48
  • [super](http://rhettinger.wordpress.com/2011/05/26/super-considered-super/) calls the cursor method of (roughly speaking) a parent class of MyConnect. In this case, `sqlite3.Connection.cursor`. – unutbu May 15 '14 at 16:51
  • More accurately, `super(MyConnect, self).cursor()` calls the cursor method of the next class in `MyConnect`'s MRO after `type(self)`. That [may or may not be a parent class](http://stackoverflow.com/q/5033903/190597) of `MyConnect`. – unutbu May 15 '14 at 21:31