سؤال

to access Python objects in Java using Jython, it's necessary to create a Java interface and use coersion (PyObject.__java__()) to assign the object to a Java reference. (http://www.jython.org/faq2.html)

The problem is that the Python library I'm trying to use does not have gets and sets, and I don't want to change the library code if I can.

Is there a way to get those public variables without having to implement Python classes to subclass and expose those attributes through methods?

Thanks.

هل كانت مفيدة؟

المحلول

You can access the attributes from a PyObject directly by using the __getattr__(PyString) and __setattr__(PyString, PyObject) methods.

You can get an attribute with:

PyObject pyObject = ...;
// Get attribute: value = getattr(obj, name)
//            OR: value = obj.__getattr__(name)
PyString attrName = Py.newString("some_attribute");
PyObject attrValue = pyObject.__getattr__(attrName);
  • WARNING: Make sure to use __getattr__(PyString) because __getattr__(String) only works for interned strings.

You can also set an attribute with:

PyObject pyObject = ...;
// Set attribute: setattr(obj, name, value)
//            OR: obj.__setattr__(name, value)
PyString attrName = Py.newString("some_attribute");
PyObject attrValue = (PyObject)Py.newString("A string as the new value.");
pyObject.__setattr__(attrName, attrValue);
  • NOTE: The value does not have to be a PyString. It just has to be a PyObject.

  • WARNING: Make sure to use __setattr__(PyString, PyObject) because __setattr__(String, PyObject) only works for interned strings.

Also, you can call a python method using __call__(PyObject[] args, String[] keywords):

PyObject pyObject = ...;

// Get method: method = getattr(obj, name)
//         OR: method = obj.__getattr__(name)
PyString methodName = Py.newString("some_method");
PyObject pyMethod = pyObject.__getattr__(methodName);

// Prepare arguments.
// NOTE: args contains positional arguments followed by keyword argument values.
PyObject[] args = new PyObject[] {arg1, arg2, ..., kwarg1, kwarg2, ...};
String[] keywords = new String[] {kwname1, kwname2, ...};

// Call method: result = method(arg1, arg2, ..., kwname1=kwarg1, kwname2=kwarg2, ...)
PyObject pyResult = pyMethod.__call__(args, keywords);
  • NOTE: I cannot explain why the keyword names are String here when getting an attribute by name requires PyString.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top