循环遍历Python / IronPython对象方法
如何正确地遍历一个Python对象的方法并调用它们?
假设我们有一个对象:
class SomeTest():
def something1(self):
print "something 1"
def something2(self):
print "something 2"
4 个回答
这段代码会查找obj
里面的所有内容,并把结果存储到一个叫做mapping的地方。在这个mapping里,键是属性的名字。具体来说,它会做这样的事情:dict((k, v()) for (k, v) in obj.__dict__.iteritems() if k.startswith('something'))
。
方法、函数和其他可调用对象的区别...
(这是为了回应Unknown帖子中的评论。)
首先,需要说明的是,除了用户自己定义的方法,还有内置的方法。内置方法就像文档中提到的那样,实际上是“内置函数的另一种表现形式”(它是一个围绕C语言函数的包装器)。
至于用户定义的方法,正如Unknown引用的那句话所说:
用户定义的方法对象结合了 一个类、一个类的实例(或者是None) 和任何可调用的对象(通常是一个 用户定义的函数)。
但这并不意味着“任何定义了__call__
并且附加到对象上的东西都是方法。” 方法是可调用的,但可调用的东西不一定是方法。用户定义的方法是对上述引用内容的包装。
希望下面这个输出(来自我手头的Python 2.5.2)能帮助你理解这个区别:
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)
>>>
另外,我还想补充一些相关的输出...
>>> class B(object):
pass
>>> b = B()
>>> b.test = test_func # Putting the function on the instance, not class
>>> type(b.test)
<type 'function'>
>>>
我不会添加更多的输出,但你也可以把一个类作为另一个类或实例的属性,尽管类是可调用的,但你不会得到一个方法。方法是通过非数据描述符实现的,如果你想了解它们是如何工作的,可以查一下描述符的相关内容。
你可以使用inspect模块来获取类(或实例)中的成员:
>>> 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()这个函数会返回一个包含元组的列表,每个元组里有两个部分:一个是名字,一个是成员。getmembers()的第二个参数是一个条件,用来过滤返回的列表(在这个例子中,它只返回方法对象)。