I've been working on serialising a n-dimensional array into a 1-dimensional "array" database:
from collections import Iterable, Mapping
import sqlite3
def pass_many(vals, some_funct, args=()):
if not vals:
return
if isinstance(vals, Iterable) and not isinstance(vals, (basestring, Mapping)):
for v in vals:
pass_many(v, some_funct, args)
else:
some_funct(vals, *args)
def counter(func):
def wrapper(v, *args, **kwargs): # added 'v' arg to no avail
wrapper.count = wrapper.count + 1
test_var_args(v, *args, **kwargs)
#return func(*args, **kwargs)
wrapper.count = 0
return wrapper
def test_var_args(farg, *args):
print "formal arg:", farg
for arg in args:
print "another arg:", arg
@counter
def insert(val, cursor, table="wordlist", logfile="queries.log"):
print val, cursor, table, logfile
if val:
if isinstance(val, (basestring, Mapping)):
val = '\"' + val + '\"'
else: val = str(val)
query = "insert into tablename values (?);".replace('tablename', table).replace('?', val)
#if logfile: to_logfile(query + '\n', logfile)
cursor.execute(query)
if __name__ == '__main__':
connection = sqlite3.connect('andthensome.db')
cursor = connection.cursor()
cursor.execute("create table array (word text);")
pass_many([["foo", "bar"], "pew"], insert, cursor)
connection.commit()
cursor.execute("select * from array;") # wrapped select function omitted for brevity
print "insert() was called", insert.count, "times, and db now contains:\n", cursor.fetchall()
cursor.close()
Output:
formal arg: foo
formal arg: bar
formal arg: pew
insert() was called 3 times, and db now contains:
[]
Output uncommenting #return func(*args, **kwargs)
:
formal arg: foo
Traceback (most recent call last):
Line 42, in <module>
pass_many([["foo", "bar"], "pew"], insert, cursor)
Line 9, in pass_many
pass_many(v, some_funct, args)
Line 9, in pass_many
pass_many(v, some_funct, args)
Line 11, in pass_many
some_funct(vals, *args)
Line 17, in wrapper
return func(*args, **kwargs)
TypeError: insert() takes at least 2 arguments (0 given)
Expected output (omitting debug function):
insert() was called 3 times, and db now contains:
["foo","bar","pew"]
Unfortunately it doesn't seem like the insert
function decorated with counter
is being passed arguments correctly.
What am I doing wrong?
One problem seems to be that you are using
*args
to expand yourargs
argument, but you pass incursor
as the value of that argument without wrapping it in a tuple. Thus your eventual call isinsert("foo", *cursor)
, when you seem to want it to beinsert("foo", cursor)
. Try doingpass_many([["foo", "bar"], "pew"], insert, (cursor,))
.I think what is happening is that when you do this, your
test_var_args
function is consuming the cursor object (which is apparently iterable) and thus leaving no more arguments to be expanded in the subsequent call to the realinsert
function.Editd after your response: Don't you actually want to pass
v
to yourfunc
call? Your insert function as written takes two arguments,v
andcursor
, but you call it with onlycursor
. Why are you wrappinginsert
? What is the extra argument supposed to do? You don't use it in the wrapper, and you don't pass it to the underlying function, so what is its purpose?