What is the proper way to loop over a Python object's methods and call them?
Given the object:
class SomeTest():
def something1(self):
print "something 1"
def something2(self):
print "something 2"
You can use the inspect module to get class (or instance) members:
>>> class C(object):
... a = 'blah'
... def b(self):
... pass
...
...
>>> c = C()
>>> inspect.getmembers(c, inspect.ismethod)
[('b', <bound method C.b of <__main__.C object at 0x100498250>>)]
getmembers() returns a list of tuples, where each tuple is (name, member). The second argument to getmembers() is the predicate, which filters the return list (in this case, returning only method objects)
Methods vs. functions and other types of callables...
(To address the issue in the comments in Unknown's post.)
First, it should be noted that, in addition to user-defined methods, there are built-in methods, and a built-in method is, as the doc at http://docs.python.org/reference/datamodel.html says, "really a different disguise of a built-in function" (which is a wrapper around a C function.)
As for user-defined methods, as Unknown's cited quote says:
A user-defined method object combines a class, a class instance (or None) and any callable object (normally a user-defined function).
But this does not mean that "anything that defines __call__
and is attached to an object is a method." A method is a callable, but a callable is not necessarily a method. User-defined methods are wrappers around what the quote says.
Hopefully this output (from Python 2.5.2 which I have handy) will show the distinction:
IDLE 1.2.2
>>> class A(object):
x = 7
>>> A # show the class object
<class '__main__.A'>
>>> a = A()
>>> a # show the instance
<__main__.A object at 0x021AFBF0>
>>> def test_func(self):
print self.x
>>> type(test_func) # what type is it?
<type 'function'>
>>> dir(test_func) # what does it have?
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__',
'__getattribute__', '__hash__', '__init__', '__module__', '__name__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__str__', 'func_closure', 'func_code', 'func_defaults', 'func_dict',
'func_doc', 'func_globals', 'func_name']
>>> # But now let's put test_func on the class...
>>> A.test = test_func
>>> type(A.test) # What type does this show?
<type 'instancemethod'>
>>> dir(A.test) # And what does it have?
['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__get__',
'__getattribute__', '__hash__', '__init__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__str__', 'im_class',
'im_func', 'im_self']
>>> # See, we just got a wrapper, and the function is in 'im_func'...
>>> getattr(A.test, 'im_func')
<function test_func at 0x0219F4B0>
>>> # Now to show bound vs. unbound methods...
>>> getattr(a.test, 'im_self') # Accessing it via the instance
<__main__.A object at 0x021AFBF0>
>>> # The instance is itself 'im_self'
>>> a.test()
7
>>> getattr(A.test, 'im_self') # Accessing it via the class returns None...
>>> print getattr(A.test, 'im_self')
None
>>> # It's unbound when accessed that way, so there's no instance in there
>>> # Which is why the following fails...
>>> A.test()
Traceback (most recent call last):
File "<pyshell#25>", line 1, in <module>
A.test()
TypeError: unbound method test_func() must be called with A instance as
first argument (got nothing instead)
>>>
And - editing to add the following additional output, which is also relevant...
>>> class B(object):
pass
>>> b = B()
>>> b.test = test_func # Putting the function on the instance, not class
>>> type(b.test)
<type 'function'>
>>>
I wont add more output, but you could also make a class an attribute of another class or instance, and, even though classes are callable, you would not get a method. Methods are implemented using non-data descriptors, so look up descriptors if you want more info on how they work.
This code snippet will call anything it will find in obj
and store results in mapping, where key is attribute name — dict((k, v()) for (k, v) in obj.__dict__.iteritems() if k.startswith('something'))
Edit
Daniel, you are wrong.
http://docs.python.org/reference/datamodel.html
User-defined methods
A user-defined method object combines a class, a class instance (or None) and any callable object (normally a user-defined function).
Therefore, anything that defines __call__ and is attached to an object is a method.
Answer
The proper way to see what elements an object has is to use the dir() function.
Obviously this example only works for functions that take no arguments.
a=SomeTest()
for varname in dir(a):
var = getattr(a, varname)
if hasattr(var, "__call__"):
var()
来源:https://stackoverflow.com/questions/928990/looping-over-a-python-ironpython-object-methods