简体   繁体   中英

Get Python arguments using Jython in Java

I am trying to parse a python script to get the functions names and their arguments, I need to do it using java.

I managed to get their names using Jython but I can't find any way to get their arguments (name, number of them?).

Python example :

def multiply_by_two(number):
    """Returns the given number multiplied by two

    The result is always a floating point number.
    This keyword fails if the given `number` cannot be converted to number.
    """
    return float(number) * 2

def numbers_should_be_equal(first, second):
    print '*DEBUG* Got arguments %s and %s' % (first, second)
    if float(first) != float(second):

Java code:

PythonInterpreter interpreter = new PythonInterpreter();
interpreter.execfile(file.getAbsolutePath());
PyStringMap map=(PyStringMap)interpreter.getLocals();
for (Object key : map.keys()) {
    Object o=map.get(Py.java2py(key));                          
    if (o instanceof PyFunction) {
        System.out.println((String)key); // the function name
        PyFunction function = (PyFunction) o; 
    }
}

I start to lose hope about finding a way to do it...

If anyone have an idea, even without using Jython

Thank you

The internal __code__ dictionary attribute of functions has a co_varnames tuple attribute for function variable names, for example:

def t(t1, t2): pass
t.__code__.co_nlocals

>>>  ('t1', 't2')

There is also t.__defaults__ for keyword arguments with defaults.

As __code__ is internal implementation though, it is subject to change across interpreters. AFAIK, it is part of specification as of Python 2.6+.

I used the answer from mata :

Would doing in in python using inspect.getargspec() be an option, eg after execfile do something like

 interpreter.exec("import inspect"); PyStringMap map=(PyStringMap)interpreter.eval("dict([(k, inspect.getargspec(v)) for (k, v) in locals().items() if inspect.isfunction(v)]) ") 

Here is the working code:

PythonInterpreter interpreter = new PythonInterpreter();
interpreter.execfile(file.getAbsolutePath());
interpreter.exec("import inspect"); 
PyDictionary dico=(PyDictionary) interpreter.eval("dict([(k, inspect.getargspec(v).args) for (k, v) in locals().items() if inspect.isfunction(v)])"); 
ConcurrentMap<PyObject, PyObject> map= dico.getMap();
map.forEach((k,v)->{
    System.out.println(k.toString());   
    System.out.println(v.toString());   
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM