1

注意,这确实是 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 类?

4

1 回答 1

0

所以我很确定你也可以使用不理想的形式BaseClass.method(self, *args, **kwargs)来获得你正在寻找的行为。那是对基类方法的“老派”(2.2 之前)访问。

于 2013-04-29T16:32:17.860 回答