修改:您可以在此处获取完整的来源: http://pastebin.com/m26693
再次编辑:我在pastebin页面添加了一些亮点。 http://pastebin.com/m10f8d239
我可能会后悔问这么长的问题,但我对这个错误感到困惑,我可以使用一些指导。您将不得不运行此代码(编辑:不再。我不能包含所有代码 - 它被截断)以帮助真正看到发生了什么,除非您是上帝或其他什么,然后通过各种方式计算出来而不运行它。实际上我希望我能够很好地解释它,所以没有必要,如果我没有做到这一点,我会道歉。
首先我会给你一些输出。 (编辑:下面有新的输出)
argc 1 [<__main__.RESULT instance at 0x94f91ec>]
(<__main__.RESULT instance at 0x9371f8c>, <__main__.RESULT instance at 0x94f91ec>)
None
bar
internal error: unknown result type 0
argc 1 [<__main__.RESULT instance at 0x94f92ac>]
(<__main__.RESULT instance at 0x94f91ac>, <__main__.RESULT instance at 0x94f92ac>)
None
bar
internal error: unknown result type 0
argc 1 [<__main__.RESULT instance at 0x94f91ec>]
(<__main__.RESULT instance at 0x94f91ec>,)
String: 'bar'
我们在输出中有3个分区。请注意,argc始终为1.在打印的位置,构建了一个参数列表以传递给插件(插件只是表达式解释器中的命令。大部分代码都是表达式解释器。)列表跟随argc的单个RESULT实例表示是参数列表。一旦到达被调用的Python方法,下一行就是参数列表。请注意,此时它有两个参数。这两个中的第一个是垃圾。第二个是我想要的。但是,正如您在“argc 1”开头的行中所看到的那样,参数列表始终为1 RESULT wide。流浪的争论来自哪里?
就像我说的那样,输出中有3个分区。第一部分本身就是一个阶级。第二个分部是一个子类。第三部门根本就没有阶级/实例。输出我预期的唯一分区是第3分区。注意它在调用之前和调用中都有1个参数成员,最后一行是预期的输出。它只是回显/返回参数“bar”。
我应该注意变量参数列表是否有任何特殊之处?我的意思是:
def foo(result, *argv):
print argv[0]
我真的认为这个bug与此有关,因为这就是垃圾似乎来自 - 在调用和执行到达方法之间。
编辑:好的,所以他们限制了这些问题的大小。 :)我会尽我所能来展示正在发生的事情。这是EvalTree的相关部分。请注意,此代码中只有2个分区。我弄乱了其他文件并删除了它。
def EvalTree(self, Root):
type = -1
number = 0.0
freeme = 0
if Root.Token == T_NUMBER or Root.Token == T_STRING:
return 0
elif Root.Token == T_VARIABLE:
self.CopyResult(Root.Result, Root.Variable.value)
return 0
elif Root.Token == T_FUNCTION:
argc = Root.Children
param = resizeList([], argc, RESULT)
print "argc", argc
for i in range(argc):
self.EvalTree(Root.Child[i])
param[i] = Root.Child[i].Result
self.DelResult(Root.Result)
Root.Function.func(Root.Result, *param) # I should have never ever programmed Lua ever.
return 0
这是插件的类。
class Foo:
def __init__(self, visitor):
visitor.AddFunction("foo", -1, self.foo)
def foo(self, result, *argv):
print argv
这就是全部执行的地方。
if __name__ == "__main__":
evaluator = Evaluator()
expression = "foo2('bar')"
#expression = "uptime('test')"
evaluator.SetVariableString("test", "Foo")
def func(self, result, *arg1):
print arg1
evaluator.SetResult(result, R_STRING, evaluator.R2S(arg1[0]))
evaluator.AddFunction('foo2', -1, func)
result = RESULT(0, 0, 0, None)
tree = evaluator.Compile(expression)
if tree != -1:
evaluator.Eval(tree, result)
if result.type == R_NUMBER:
print "Number: %g" % (evaluator.R2N(result))
elif result.type == R_STRING:
print "String: '%s'" % (result.string) #(evaluator.R2S(result))
elif result.type == (R_NUMBER | R_STRING):
print "String: '%s' Number: (%g)" % (evaluator.R2S(result), evaluator.R2N(result))
else:
print "internal error: unknown result type %d" % (result.type)
expression = "foo('test')"
result = RESULT(0, 0, 0, None)
tree = evaluator.Compile(expression)
if tree != -1:
evaluator.Eval(tree, result)
if result.type == R_NUMBER:
print "Number: %g" % (evaluator.R2N(result))
elif result.type == R_STRING:
print "String: '%s'" % (result.string) #(evaluator.R2S(result))
elif result.type == (R_NUMBER | R_STRING):
print "String: '%s' Number: (%g)" % (evaluator.R2S(result), evaluator.R2N(result))
else:
print "internal error: unknown result type %d" % (result.type)
这是新输出:
argc 1
(<__main__.RESULT instance at 0x9ffcf4c>,)
String: 'bar'
argc 1
(<__main__.RESULT instance at 0xa0030cc>, <__main__.RESULT instance at 0xa0030ec>)
internal error: unknown result type 0
答案 0 :(得分:2)
您的代码似乎被截断了,所以我无法查看它。
鉴于您只获得了类中定义的方法的额外参数,可能是self
变量吗? Python类上的每个方法都接收self
作为第一个参数,如果你不考虑它,你就会出错。
换句话说,应该这样:
def foo(result, *argv):
print argv[0]
实际上就是这样:
def foo(self, result, *argv):
print argv[0]
如果是这样,那么self
传统上保留的值将被分配给result
,您的结果值将位于argv的第一个位置。
如果不是这样,你需要提供更多代码。至少,实际运行测试的代码。
答案 1 :(得分:1)
在Foo课程中,当你打电话
时
def __init__(self, visitor):
visitor.AddFunction("foo", -1, self.foo)
...您正在添加所谓的“绑定”方法参数(即self.foo
)。它就像一个已经指定了self参数的函数。原因是,当你调用self.foo(bar,baz)时,你不会在参数列表中再次指定“self”。如果你打电话
def __init__(self, visitor):
visitor.AddFunction("foo", -1, Foo.foo)
...你得到与你的免费功能相同的结果。但是,我认为这不是你想要的。此外,EvalTree将自己的self
作为第一个arg传递给函数。我想你可能想要的是这样声明foo:
class Foo:
def __init__(self, visitor):
visitor.AddFunction("foo", -1, self.foo)
def foo(self, tree, result, *argv):
print argv