注意,这确实是 Jython 爱好者的问题,但似乎突出了语言的设计困难
如果我这样做
class XTreeModel( DefaultTreeModel ):
def fireTreeNodesInserted( self, source, path, child_indices, children ):
print "fire nodes inserted"
super( XTreeModel, self ).fireTreeNodesInserted( source, path, child_indices, children )
我得到无限递归。当我第一次遇到这个时,我非常困惑。我还是不明白为什么代码不能调用Java超类(基类)的方法,而是再次调用自己(!)。为了防止这种情况我去
class XTreeModel( DefaultTreeModel ):
def fireTreeNodesInserted( self, source, path, child_indices, children ):
print "fire nodes inserted"
self.super__fireTreeNodesInserted( source, path, child_indices, children )
...而且我从开始使用 Jython 开始了解到,这些调用 Java 基类的“super__XXX”方法实际上是由 Jython 解释器自发创建的,并且只有当您覆盖 Jython 类中的 Java 方法时,该类的子类Java 类(如上)。就目前而言,这没问题……但是如果您不知道您的超类(基类)是否是 Java 类怎么办?我最终开发了以下实用方法:
def get_super_method( caller, code_class ):
stack_1 = inspect.stack()[ 1 ]
func_name = stack_1[ 3 ]
# unfortunately this will return code_class.func_name as standard if code_class is a derived from a Java class with method func_name
supposed_baseclass_method = getattr( super( code_class, caller ), func_name )
for baseclass in caller.__class__.__base__.__mro__:
if "org.python.proxies" in str( baseclass ):
# ... this means we have reached down as low as a Java "proxy" class without yet encountering a class with a method 'func_name',
# which means that we must return the super__XXX version
break
# confusingly, even if you go caller.__class__.__base__.__mro__ this still shows all the classes for caller, including its highest class!
if baseclass == code_class:
continue
if func_name in baseclass.__dict__:
# ... a method with the right name exists in a baseclass...
return supposed_baseclass_method
java_baseclass_method = getattr( caller, "super__%s" % func_name )
return java_baseclass_method
你打电话去,例如:
class XTreeModel( DefaultTreeModel ):
def fireTreeNodesInserted( self, source, path, child_indices, children ):
print "X fire nodes inserted"
get_super_method( self, XTreeModel )(source, path, child_indices, children )
class XXTreeModel( XTreeModel ):
def fireTreeNodesInserted( self, source, path, child_indices, children ):
print "XX fire nodes inserted"
get_super_method( self, XXTreeModel )(source, path, child_indices, children )
这里 XXTreeModel 中的 get_super_method 返回 super( XXTreeModel, self )... 而 XTreeModel 中的 get_super_method 返回 self.super__fireTreeNodesInserted 所以... 也许您可以只查看传递给 get_super_method 的 code_class ,如果它在它的直接基类的名称意味着您返回 super__XXX 版本,对吗?呃,不,它有点复杂:
class XTreeModel( DefaultTreeModel ):
def do_some_stuff( self ):
print "do stuff"
class XXTreeModel( XTreeModel ):
def fireTreeNodesInserted( self, source, path, child_indices, children ):
print "XX fire nodes inserted"
get_super_method( self, XXTreeModel )(source, path, child_indices, children )
在这个例子中,XXTreeModel 有一个 Jython 类作为它的基类,但是这个基类 (XTreeModel) 没有覆盖感兴趣的方法......所以实际上 XXTreeModel 中的 get_super_method() 需要返回 super__ fireTreeNodesInserted... ... 所以这个实用方法似乎解决了这个问题:你不需要知道你的基类是什么类型的类,它是否覆盖了Java方法等等。无论如何,我想知道这个曲折的过程是否必要,但是谷歌搜索“jython super”等产生了 10 年前的错误条目,说“不推荐使用 super__ 方法”。
有没有更好的方法来完成对超类方法的调用,其中您的第一个基类(当您向下移动类时)使用所寻求的方法实际上是一个 Java 类?