gpt4 book ai didi

python - getattr 与 inspect.getmembers

转载 作者:太空狗 更新时间:2023-10-30 00:30:17 34 4
gpt4 key购买 nike

可以使用 getattr(obj, attr) 或 inspect.getmembers(obj) 获取对象属性,然后按名称过滤:

import inspect

class Foo(object):

def __init__(self):

self.a = 100

def method(self): pass

foo = Foo()
method_by_getattr = getattr(foo, 'method')

foo_members = inspect.getmembers(foo)
method_by_inspect = [member[1] for member in foo_members
if member[0] == "method"][0]

print (id(method_by_getattr), method_by_getattr, type(method_by_getattr))
print (id(method_by_inspect), method_by_inspect, type(method_by_inspect))

a_by_getattr = getattr(foo, "a")
a_by_inspect = [member[1] for member in foo_members
if member[0] == "a"][0]

print (id(a_by_getattr), a_by_getattr, type(a_by_getattr))
print (id(a_by_inspect), a_by_inspect, type(a_by_inspect))

# (38842160L, <bound method Foo.method of <__main__.Foo object at 0x00000000025EF390>>, <type 'instancemethod'>)
# (39673576L, <bound method Foo.method of <__main__.Foo object at 0x00000000025EF390>>, <type 'instancemethod'>)
# (34072832L, 100, <type 'int'>)
# (34072832L, 100, <type 'int'>)

对于“a”属性,getattr 和 inspect.getmembers 返回相同的对象。但是对于方法“method”,它们返回不同的对象(从不同的 id 可以看出)。

为什么会这样?

最佳答案

millimoose 获得绿色复选标记,但我想我要添加一点。

tl;dr

绑定(bind)方法对象是 transient 的。也就是说,每次您抓取它们时,它们都会重新创建。

class Foo(object):
def bar(object): pass

foo = Foo()
m1 = foo.bar
m2 = foo.bar
print (id(m1))
print (id(m2))

# 38121264
# 38952752

更多细节:描述符协议(protocol)

每次获取绑定(bind)方法对象时都会重新创建它们,因为存储在类中的函数对象实现了 descriptor protocol .

bar 函数存储在类 dict 中:

class Foo(object):
def bar(object): pass

print (Foo.__dict__['bar'])

# <function bar at 0x00000000025F2208>

当 Foo 实例试图访问 bar 时,它没有。所以它在它的类中查找它并在类字典中找到它。根据描述符协议(protocol),函数对象实现了一个 __get__ 方法。那么实际上调用获取绑定(bind)方法的是这样的:

print(Foo.__dict__['bar'].__get__(foo, Foo))

# <bound method Foo.bar of <__main__.Foo object at 0x00000000025719B0>>

相当于:

print (foo.bar)

# <bound method Foo.bar of <__main__.Foo object at 0x00000000025719B0>>

你可以像这样得到原始函数:

print (foo.bar.im_func) # Python 2.x

# <function bar at 0x00000000025F2208>

print (foo.bar.__func__) # Python 3.x

# <function bar at 0x00000000025F2208>

关于python - getattr 与 inspect.getmembers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12848507/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com