从 Jython 访问受保护的 Java 属性
Access protected Java attribute from Jython
我正在使用 Java Swing 使用 Jython 构建一个文本编辑器。我遇到了 CompoundEdit,一个 Swing class,它有一个文本编辑器的编辑操作列表。此属性是受保护的,这意味着我无法从另一个 class 直接访问它,但我可以从扩展它的其他 class 访问它。因此,如果我创建一个扩展 CompoundEdit
的 MyEdit
class,MyEdit
应该可以访问编辑列表。
这就是我正在尝试的:
class MyEdit(CompoundEdit):
def __init__(self):
super(CompoundEdit, self).__init__()
print(dir(self)) # Doesn't show the edits
self.nammu_edits = super(CompoundEdit, self).edits
运行 这给了我这个错误:
AttributeError: 'super' object has no attribute 'edits'
作为参考,这是 dir
返回的内容:
['__class__', '__copy__', '__deepcopy__', '__delattr__', '__dict__', '__doc__', '__ensure_finalizer__', '__eq__', '__format__', '__getattribute__', '__hash__', '__initProxy__', '__init__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__subclasshook__', '__supernames__', '__unicode__', '__weakref__', '_getPyInstance', '_getPySystemState', '_setPyInstance', '_setPySystemState', 'addEdit', 'canRedo', 'canUndo', 'class', 'classDictInit', 'clone', 'die', 'doPrint', 'end', 'equals', 'finalize', 'getClass', 'getPresentationName', 'getRedoPresentationName', 'getUndoPresentationName', 'hashCode', 'inProgress', 'isInProgress', 'isSignificant', 'lastEdit', 'notify', 'notifyAll', 'presentationName', 'redo', 'redoPresentationName', 'replaceEdit', 'significant', 'toString', 'undo', 'undoPresentationName', 'wait']
这是 CompoundEdit.java 代码的摘录:
public class CompoundEdit extends AbstractUndoableEdit {
/**
* True if this edit has never received <code>end.
*/
boolean inProgress;
/**
* The collection of <code>UndoableEdits
* undone/redone en masse by this <code>CompoundEdit.
*/
protected Vector<UndoableEdit> edits;
public CompoundEdit() {
super();
inProgress = true;
edits = new Vector<UndoableEdit>();
}
我已经从 Java 尝试过完全相同的方法,它让我可以访问 edits
。我在 Jython 版本中做错了什么吗? Jython 中是否有一种特殊的方式来访问受保护的变量?在文档中它提到了一些关于调用 super__<method>()
的内容,但我在这种情况下尝试过它,但它也不起作用。
@mzjn 是对的。设置 python.security.respectJavaAccessibility = false
是从子类访问受保护字段的唯一方法。这是由于org.python.core.PyJavaType.init(Class<?>, Set<PyJavaType>)
中的这段代码:
// Add fields declared on this type
Field[] fields;
if (Options.respectJavaAccessibility) {
// returns just the public fields
fields = forClass.getFields();
} else {
fields = forClass.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
}
}
但是,您 可以 调用受保护的方法而无需将 respectJavaAccessibility
设置为 false
,因为方法查找使用不同的算法。 IMO 这是一个错误,我找不到任何提及此行为的意图。
或者直接使用Java反射获取保护字段值:
class MyEdit(CompoundEdit):
#...
def get_edits(self):
edits_field = CompoundEdit.getDeclaredField('edits')
edits_field.setAccessible(True)
return edits_field.get(self)
我正在使用 Java Swing 使用 Jython 构建一个文本编辑器。我遇到了 CompoundEdit,一个 Swing class,它有一个文本编辑器的编辑操作列表。此属性是受保护的,这意味着我无法从另一个 class 直接访问它,但我可以从扩展它的其他 class 访问它。因此,如果我创建一个扩展 CompoundEdit
的 MyEdit
class,MyEdit
应该可以访问编辑列表。
这就是我正在尝试的:
class MyEdit(CompoundEdit):
def __init__(self):
super(CompoundEdit, self).__init__()
print(dir(self)) # Doesn't show the edits
self.nammu_edits = super(CompoundEdit, self).edits
运行 这给了我这个错误:
AttributeError: 'super' object has no attribute 'edits'
作为参考,这是 dir
返回的内容:
['__class__', '__copy__', '__deepcopy__', '__delattr__', '__dict__', '__doc__', '__ensure_finalizer__', '__eq__', '__format__', '__getattribute__', '__hash__', '__initProxy__', '__init__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__subclasshook__', '__supernames__', '__unicode__', '__weakref__', '_getPyInstance', '_getPySystemState', '_setPyInstance', '_setPySystemState', 'addEdit', 'canRedo', 'canUndo', 'class', 'classDictInit', 'clone', 'die', 'doPrint', 'end', 'equals', 'finalize', 'getClass', 'getPresentationName', 'getRedoPresentationName', 'getUndoPresentationName', 'hashCode', 'inProgress', 'isInProgress', 'isSignificant', 'lastEdit', 'notify', 'notifyAll', 'presentationName', 'redo', 'redoPresentationName', 'replaceEdit', 'significant', 'toString', 'undo', 'undoPresentationName', 'wait']
这是 CompoundEdit.java 代码的摘录:
public class CompoundEdit extends AbstractUndoableEdit {
/**
* True if this edit has never received <code>end.
*/
boolean inProgress;
/**
* The collection of <code>UndoableEdits
* undone/redone en masse by this <code>CompoundEdit.
*/
protected Vector<UndoableEdit> edits;
public CompoundEdit() {
super();
inProgress = true;
edits = new Vector<UndoableEdit>();
}
我已经从 Java 尝试过完全相同的方法,它让我可以访问 edits
。我在 Jython 版本中做错了什么吗? Jython 中是否有一种特殊的方式来访问受保护的变量?在文档中它提到了一些关于调用 super__<method>()
的内容,但我在这种情况下尝试过它,但它也不起作用。
@mzjn 是对的。设置 python.security.respectJavaAccessibility = false
是从子类访问受保护字段的唯一方法。这是由于org.python.core.PyJavaType.init(Class<?>, Set<PyJavaType>)
中的这段代码:
// Add fields declared on this type
Field[] fields;
if (Options.respectJavaAccessibility) {
// returns just the public fields
fields = forClass.getFields();
} else {
fields = forClass.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
}
}
但是,您 可以 调用受保护的方法而无需将 respectJavaAccessibility
设置为 false
,因为方法查找使用不同的算法。 IMO 这是一个错误,我找不到任何提及此行为的意图。
或者直接使用Java反射获取保护字段值:
class MyEdit(CompoundEdit):
#...
def get_edits(self):
edits_field = CompoundEdit.getDeclaredField('edits')
edits_field.setAccessible(True)
return edits_field.get(self)