views:

296

answers:

2

I want to get the names of the keyword arguments of the methods of a class. I think I understood how to get the names of the methods and how to get the variable names of a specific method, but I don't get how to combine these:

class A(object):
    def A1(self, test1=None):
        self.test1 = test1
    def A2(self, test2=None):
        self.test2 = test2
    def A3(self):
        pass
    def A4(self, test4=None, test5=None):
        self.test4 = test4
        self.test5 = test5

a = A()

# to get the names of the methods:

for methodname in a.__class__.__dict__.keys():
    print methodname

# to get the variable names of a specific method:

for varname in a.A1.__func__.__code__.co_varnames:
    print varname

# I want to have something like this:
for function in class:
    print function.name
    for varname in function:
        print varname

# desired output:
A1
self
test1
A2
self
test2
A3
self
A4
self
test4
test5

I will have to expose the names of the methods and their arguments to an external API. I have written a twisted app to link to the mentioned api and this twisted app will have to publish this data via the api.

So, I think I will use something like:

for methodname in A.__dict__.keys():
if not methodname.startswith('__'):
    print methodname
    for varname in A.__dict__[methodname].__code__.co_varnames:
        print varname

Once, the surroundings get more stable I will think about a better solution.

+4  A: 

Well, as a direct extension of what you did:

for varname in a.__class__.__dict__['A1'].__code__.co_varnames:
    print varname

prints:

self
test1

P.S.: to be honest, I have a feeling this can be done more elegantly...

For example, you can replace a.__class__ with A, but you knew that ;-)

Eli Bendersky
Thanks! If you know a better solution, you're welcome. My monday morning brain is just a little bit... you know... ;-)
daccle
There is nothing helpful about showing people how to do silly things.
ironfroggy
@ironfroggy why do you think it is a silly thing?
daccle
@daccle: Please update your question to explain why you need introspection and why you can't simply read the source.
S.Lott
@ironfroggy: People sometimes implement tools for working with code (intellisense, etc), that require the usage of such techniques. I do not recommend using it in any "normal" code
Eli Bendersky
+2  A: 
import inspect

for name, method in inspect.getmembers(a, inspect.ismethod):
    print name
    (args, varargs, varkw, defaults) = inspect.getargspec(method)
    for arg in args:
        print arg
Eddy Pronk
I have seen a lot of examples using inspect module. Why is using inspect a good idea? Why not using classes own methods to do the job?
daccle
@daccle: my guess is that `inspect` has been there before classes were allowing such levels of introspection
Eli Bendersky
inspect api is clean. Using it makes code more readable I think.
Eddy Pronk
+1 This is (imo) the correct way. All the double underscores in Eli Bendersky's answer should give away that he's doing something fishy ;-)
ChristopheD