Доступ к защищенному атрибуту Java из Jython - PullRequest
0 голосов
/ 15 октября 2018

Я создаю текстовый редактор с помощью Jython, используя Java Swing.Я встречал CompoundEdit , класс Swing, у которого есть список действий по редактированию из текстового редактора.Этот атрибут защищен, что означает, что я не могу получить к нему доступ непосредственно из другого класса, но я могу получить доступ из других классов, которые его расширяют.Итак, если я создаю класс MyEdit, который расширяет CompoundEdit, 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>(), но я попробовал это для этого случая, и он также не работает.

1 Ответ

0 голосов
/ 01 ноября 2018

@ 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)
...