Java jython-有没有办法避免使用;超级;方法?
注:这确实是Jython爱好者的一个问题,但似乎突出了语言中的设计困难 如果我这样做Java jython-有没有办法避免使用;超级;方法?,java,jython,superclass,Java,Jython,Superclass,注:这确实是Jython爱好者的一个问题,但似乎突出了语言中的设计困难 如果我这样做 class XTreeModel( DefaultTreeModel ): def fireTreeNodesInserted( self, source, path, child_indices, children ): print "fire nodes inserted" super( XTreeModel, self ).fireTreeNodesInserted( source
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以来,我了解到,这些调用“super_uxxx”方法的Java基类实际上是由Jython解释器自发创建的,并且仅当您重写Jython类中的Java方法,而Jython类是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_方法返回super(XXTreeModel,self)。。。而XTreeModel中的get_super_方法返回self.super_FireTreeNodeInserted
所以也许你可以看看传递给get超级方法的代码类,如果它的直接基类中有“org.python.proxies”,这意味着你返回超级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_uufiretreenodesinserted。。。
... 所以这个实用方法似乎解决了这个问题:您不需要知道基类是什么类型的类,它是否覆盖了Java方法,等等。
无论如何,我想知道这个曲折的过程是否有必要,但谷歌搜索“jython super”等网站产生了10年前的bug条目,上面写着“super_u_;方法的使用不受欢迎”
有没有更好的方法来完成对超类方法的调用,其中您的第一个基类(当您在类中向下移动时)实际上是一个Java类???所以我很确定您可以使用不理想的
基类.method形式(self,*args,**kwargs)
来获得您想要的行为,也。这是“老派”(2.2之前)获得基本类方法的途径。谢谢。。。但如果答案这么简单的话,我就不会这么费劲了。这一点是为了满足这样一种情况,即您不知道基类是Java(代理)类还是“真正的”Jython类,它派生自层次结构较低的Java(代理)类。也许你只是希望Jython像Python一样简单。。。但是不,Java和Python结合的强大功能是需要付出代价的……好吧,它对我来说很好,但是在查看代码时,我调用的是Jython类,而不是Java类。当我以正确的形式使用super()时,我遇到了“无限递归”错误;我转向了BaseClass.method形式,一切正常。我的方法也不支持子类中的mixin,但我不需要子类。:)阿杰夫再次感谢你。。。但我的问题的重点是,当你不知道基类的名称时,你会怎么做。。。不幸的是,仅仅使用super()不起作用,事实上,对于这些“Java代理”级别的类,Jython会在需要时动态地为它们创建类型为“super\uu firetreendesinserted”的方法(请参见上文,如果您有兴趣阅读我的问题的话…),我阅读了它。记录在案,super()应该可以工作。它当前的行为是一个缺陷,Jython中的“纯python”类也有缺陷。