tags:

views:

109

answers:

2

Hi,

I'm trying to get a dict out of a method, so far I'm able to get the method name, and its arguments (using the inspect module), the problem I'm facing is that I'd like to have the default arguments too (or the argument type).

This is basically my unit test:

class Test:
    def method1(anon_type, array=[], string="string", integer=12, obj=None):
        pass

target = {"method1": [
             {"anon": "None"}, 
             {"array": "[]"}, 
             {"string": "str"}, 
             {"integer": "int"},
             {"obj": "None"}]
         }
method1_dict = get_method_dict(Test().method1)

self.assertEqual(target, method1_dict)

Here, I try to use inspect to get the method:

>>> import inspect
>>> class Class:
...     def method(self, string='str', integer=12):
...             pass
... 
>>> m_desc = inspect.getargspec(Class().method)
>>> m_desc
ArgSpec(args=['self', 'string', 'integer'], varargs=None, keywords=None, defaults=('str', 12))
>>>

but my problem is with the default args, as you see here:

>>> class Class:
...     def method(self, no_def_args, string='str', integer=12):
...             pass
... 
>>> m_desc = inspect.getargspec(Class().method)
>>> m_desc
ArgSpec(args=['self', 'no_def_args', 'string', 'integer'], varargs=None, keywords=None, defaults=('str', 12))

As you see the no_def_args is not in the defaults, so it's a problem to try to match the argument with their default arguments.

+2  A: 

what exactly is the problem? all arguments are ordered, keyword arguments should be the last in definition. do you know how to slice a list?

SilentGhost
I didn't know that if you don't order your arguments is a syntax error, and yes I know how to slice a list, thanks!
igorgue
+1  A: 

Here is what I usually do:

import inspect, itertools
args, varargs, keywords, defaults = inspect.getargspec(method1)
print dict(itertools.izip_longest(args[::-1], defaults[::-1], fillvalue=None))

-->

{'integer': 12, 'array': [], 'anon_type': None, 'obj': None, 'string': 'string'}

This will only work on python2.6

Nadia Alramli
If not specified, fillvalue defaults to None. ;)
SilentGhost