我正在用Jython编写一个文本编辑器。这个文本编辑器有一个工具栏,它用ToolbarView
类显示,并由ToolbarController
类处理。有些操作不能由ToolbarController
单独处理,因此这些操作被委托给MainController
类。在
为了避免重复代码,因为有很多操作从ToolbarController
委托给主控制器,我使用了getattr,正如我在上一个问题here中建议的那样。我还意识到我可以在ToolbarView
代码中使用相同的机制来执行按钮的操作,但我无法使其工作,最终得到一个无限循环和一个Java StackOverflowError
。在
以下是相关代码的摘录:
工具栏视图类:
from javax.swing import JToolBar, ImageIcon, JButton
class ToolbarView(JToolBar):
def __init__(self, controller):
#Give reference to controller to delegate action response
self.controller = controller
options= ['NewFile', 'OpenFile', 'SaveFile', 'CloseFile']
for option in options:
methods[option] = "on" + option + "Click"
print methods[option]
for name, method in methods.items():
button = JButton(name, actionPerformed=getattr(self, method))
self.add(button)
def __getattr__(self, name):
return getattr(self.controller, name)
工具栏控制器类:
^{pr2}$main控制器类:
^{3}$所以我期望的是,当我单击按钮时,MainController.onNewFileClick
将被执行并在控制台中打印出该消息。如果我想从ToolbarView
委托给ToolbarController
,它可以工作,但是当我把这个委托从ToolbarController
传递给主控制器时,它就不起作用了。它似乎在一个无限的循环中自我调用。我得到的错误是:
Traceback (most recent call last):
File "main.py", line 3, in <module>
MainController()
File "/home/training/Jython/controller/MainController", line 8, in __init__
self.toolbarController = ToolbarController(self)
File "/home/Jython/controller/ToolbarController.py", line 8, in __init__
self.view = ToolbarView(self)
File "/home/Jython/controller/ToolbarView.py", line 44, in __init__
button = JButton(name, actionPerformed=getattr(self, method))
File "/home/Jython/controller/ToolbarView.py", line 54, in __getattr__
return getattr(self.controller, name)
File "/home/Jython/controller/ToolbarController.py", line 15, in __getattr__
return getattr(self.mainController, name)
File "/home/Jython/controller/ToolbarController.py", line 15, in __getattr__
return getattr(self.mainController, name)
[...]
File "/home/Jython/controller/ToolbarController.py", line 15, in __getattr__
return getattr(self.mainController, name)
RuntimeError: maximum recursion depth exceeded (Java StackOverflowError)
我做错什么了?我在python中尝试过类似的方法(从一个类委托给另一个类),如果在getattr后面加一个put ()
就可以了,但是这里我感到困惑,因为JButton中的actionPerformed
。我试过了,但结果是一样的。在
你好像在用
Jython
,我真的不知道。无论如何,在python中,您重写了__getattr__
,那么您应该期望getattr
使用被重写的钩子。所以我觉得你的意思是:观察按钮是如何创建的。在
至于为什么会有这样的问题,那是因为
^{pr2}$getattr
是如何处理的。如果重写__getattr__
,则只有在尝试引用未定义的字段时才会调用此钩子:希望现在钩子是怎么工作的。在
所以so实际上是因为您引用了不属于
MainController
的内容。在在您的
MainController
中,只定义了onNewFileClick
,但您定义了3个其他选项:所以,这将发生在第二轮迭代中。由于}将被调用并打开。这就是你的调用堆栈爆炸的原因。在
MainController
没有onOpenFileClick
,一个AttributeError
将被引发,但被ToolbarController
捕获,因此被重写的{我把这归咎于
getattr
,因为我还没有那么自信地使用它,但事实证明它是相当基本的东西。在我在创建ToolbarView之后将
ToolbarController
分配给ToolbarController
,后者调用ToolbarView.__getatrr__
,后者试图访问尚不存在的self.mainController
!在这是我需要在
ToolbarController
类中进行的更改。在之前
之后:
^{pr2}$非常感谢@hustmphrr和@ArtOfWarfare的帮助。在
相关问题 更多 >
编程相关推荐