jython - 有没有办法避免使用“super__”方法?

时间:2012-10-26 09:41:40

标签: java jython superclass

对于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-base-class-calling“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,如果它的直接基类名称中有“org.python.proxies”,那意味着你返回了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类???

1 个答案:

答案 0 :(得分:0)

因此,我非常确定您可以使用非理想形式的BaseClass.method(self, *args, **kwargs)来获取您正在寻找的行为。这是“老派”(2.2之前)对基类方法的访问。