Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 装饰师不是';不要传递论点?_Python_Sqlite_Functional Programming_Decorator_Pysqlite - Fatal编程技术网

Python 装饰师不是';不要传递论点?

Python 装饰师不是';不要传递论点?,python,sqlite,functional-programming,decorator,pysqlite,Python,Sqlite,Functional Programming,Decorator,Pysqlite,我一直致力于将n维数组序列化为一维“数组”数据库: 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)): f

我一直致力于将n维数组序列化为一维“数组”数据库:

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()
输出:

formal arg: foo
formal arg: bar
formal arg: pew
insert() was called 3 times, and db now contains:
[]
输出取消注释
#返回函数(*args,**kwargs)

不幸的是,用
计数器装饰的
insert
函数似乎没有正确地传递参数


我做错了什么?

一个问题似乎是,您正在使用
*args
展开
args
参数,但您将
游标作为该参数的值传入,而没有将其包装在元组中。因此,您最终的调用是
insert(“foo”,光标)
,而您似乎希望它是
insert(“foo”,光标)
。尝试执行
传递多个([[“foo”、“bar”]、“pew”]、插入(游标),)

我认为发生的情况是,当您执行此操作时,您的
test\u var\u args
函数正在使用游标对象(这显然是可编辑的),因此在后续调用real
insert
函数时,不会留下更多要展开的参数


回答后编辑:您不想将
v
传递给您的
func
呼叫吗?您编写的insert函数接受两个参数,
v
cursor
,但您只使用
cursor
调用它。为什么要包装
insert
?额外的论点应该做什么?您不在包装器中使用它,也不将它传递给底层函数,那么它的用途是什么呢?

有两件事:首先,在
包装器()中

您已将第一个参数映射到
v
,但未将其传递到实际的
func
。最好把它完全去掉

第二,也是最重要的:

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)
请注意,当调用
some_funct()
时,您正在分解
args
参数。问题是,当调用
pass\u many()
时,给了它一个
cursor
对象作为
args
参数。这将微妙地失败。要解决此问题,您可以删除splat操作符
*
,或者,更好的选择是,在调用
pass\u many
时,可以将
游标
对象包装在元组中,如下所示:

pass_many([["foo", "bar"], "pew"], insert, (cursor,))

这仍然会给出一个错误“没有这样的表:wordlist”,但这实际上是因为您还没有定义这样的表。('wordlist'是
insert()
的默认参数)

根据@BrenBarn的建议,我将其修改为:

def counter(func):
    def wrapper(v, *args, **kwargs):
        wrapper.count = wrapper.count + 1
        test_var_args(v, *args, **kwargs)
        return func(v, *args, **kwargs)
    wrapper.count = 0

    return wrapper

pass_many([["foo", "bar"], "pew"], insert, [cursor])

装饰器中的函数调用被注释掉了吗?是的,这样调试
test\u var\u args
函数就可以一直运行
insert
来显示哪些args在何时出现。您能提供一个更简单的测试用例吗?在一个简单的无操作函数(
def func(*args,**kwargs):pass
)上使用decorator会显示问题,这将是理想的。此外,最好能准确地了解出了什么问题——例如,列出您期望的输出和实际得到的输出。您如何知道它不起作用?你期望什么样的产出?你得到了什么?如果您得到一个错误,它是什么?用当前输出更新,输出取消注释
return func(*args,**kwargs)
和预期输出。谢谢,给了我一个稍微好一点的结果:
TypeError:insert()至少接受2个参数(1个给定)
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)
pass_many([["foo", "bar"], "pew"], insert, (cursor,))
def counter(func):
    def wrapper(v, *args, **kwargs):
        wrapper.count = wrapper.count + 1
        test_var_args(v, *args, **kwargs)
        return func(v, *args, **kwargs)
    wrapper.count = 0

    return wrapper

pass_many([["foo", "bar"], "pew"], insert, [cursor])