Python 使用getattr获取方法的对象引用
比如说,我有一个名为Python 使用getattr获取方法的对象引用,python,function,object,reference,getattr,Python,Function,Object,Reference,Getattr,比如说,我有一个名为的类名为测试,方法是名为开始 >>> class Test: ... def __init__(self, *args, **kwargs): ... pass ... def start(self): ... pass ... 现在,我有一个独立的函数,名为func >>> def func(): ... print 'this is a func and not a metho
的类
名为测试
,方法是名为开始
>>> class Test:
... def __init__(self, *args, **kwargs):
... pass
... def start(self):
... pass
...
现在,我有一个独立的函数
,名为func
>>> def func():
... print 'this is a func and not a method!!!'
...
>>>
[1]
现在,t.start
是属于0xb769678c
>>> t = Test()
>>> t.start
<bound method Test.start of <__main__.Test instance at 0xb769678c>>
>>>
现在,我们可以使用内置的\uu模块从t.start
和func
中提取\uu模块。毫不奇怪,func
和t.start
属于同一个模块
,即\uu main\uu
>>> func.__module__
'__main__'
>>> t.__module__
'__main__'
>>>
[3]
现在,让我们在变量obj
>>> obj = __import__(t.start.__module__)
>>> obj
<module '__main__' (built-in)>
>>>
问题:
如何使用getattr()
和模块名[3]获取Test.start的句柄,该句柄应为
当我尝试在't.start'
上使用getattr()
时,我得到了以下回溯
>>> print getattr(obj, 'Test.start')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'Test.start'
>>>
>>>
>>> print getattr(__import__('__main__'), 'Test.start')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'Test.start'
>>>
打印getattr(对象“Test.start”)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:“模块”对象没有属性“Test.start”
>>>
>>>
>>>打印getattr(uuu导入(“uuu main”),“Test.start”)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:“模块”对象没有属性“Test.start”
>>>
换句话说,我有两个数据。是的
\uuuu导入(“\uuuu main””)
sting'Test.start'
现在,如何获取t.start
的句柄(注意这里的实例
),它应该是
我不确定您是否直接从模块中需要它(或者即使这是可能的):/
您还可以使用:
obj = __import__(t.start.__module__)
print obj.__dict__["Test"].__dict__["start"]
但是你问的是getattr()
所以…我不确定我是否理解你的问题,但我想这正是你想要的:
class Test:
def __init__(self, *args, **kwargs):
pass
def start(self):
pass
def func():
print 'this is a func and not a method!!!'
t = Test()
module = __import__(t.start.__module__)
print vars(module)['Test'].start
print vars(module)['func']
print vars(module)['t'].start
输出:
我想知道你为什么要写obj=\uuuu导入(t.start.\uu模块)
我认为应该为主模块保留一个名称,以便能够通过getattr()函数获得模块名称空间中的对象作为模块的属性
我告诉你,你不必做这个把戏。
globals()是表示主空间的全局命名空间的字典。
然后您可以编写,例如,globals()[“func”]
来获取对象func
我还通知您,除了使用getattr(N,“xyz”)
之外,还有另一种方法可以在对象N的名称空间中获得对象xyz,因为它的名称xyz
,
它是通过\uuuu dict\uuuu
方法实现的:
N.\uuuu dict\uuuu
允许访问对象的命名空间N
我想知道您的问题是否在于Python的微妙之处,它导致您出错
在你的问题中,你在一个地方写了t.\uuuuu模块
,在另一个地方写了t.start.\uuuuu模块
。
对于这两种情况,结果相同且等于“\uuuuu main\uuuuu”
然而,
1) t没有name\uuuu模块的属性
2) t甚至没有namestart
属性
如果您打印t.\uuuu dict\uuuu
您将看到结果是{}
start实际上不属于实例的命名空间t,因为它实际上属于Test的命名空间
以下代码证明了这些确认:
class Test:
def __init__(self, *args, **kwargs):
pass
def start(self):
pass
y = Test()
y.ku = 102
print 'y.__dict__',y.__dict__
print 'Test.__dict__',Test.__dict__
结果
y.__dict__ {'ku': 102}
Test.__dict__ {'start': <function start at 0x011E11B0>,
'__module__': '__main__',
'__doc__': None,
'__init__': <function __init__ at 0x011E1170>}
* globals()["func"]
<function func at 0x011C27B0>
18622384
====================================
* Test.__dict__["start"]
<function start at 0x011DEFB0>
18739120
----------------------------------------------
* getattr(Test,"start")
<unbound method Test.start>
18725304
----------------------------------------------
* getattr(t,"start")
<bound method Test.start of <__main__.Test instance at 0x011DF418>>
18725304
{'__builtins__': <module '__builtin__' (built-in)>,
'__package__': None,
't': <__main__.Test instance at 0x011DF418>,
'func': <function func at 0x011C27B0>,
'Test': <class __main__.Test at 0x011DC538>,
'__name__': '__main__',
'__doc__': None}
func ---> <function func at 0x011C2470>
18621552
obj = __import__(t.start.__module__) done
* globals()["func"]
<function func at 0x011C2470> # <== address in hexadecimal
18621552 # <== address in decimal
* obj.__dict__["func"]
<function func at 0x011C2470>
* getattr(obj, 'func')
<function func at 0x011C2470>
* getattr(__import__('__main__'), 'func')
<function func at 0x011C2470>
Test.start --> <unbound method Test.start>
18725264
----------------------------------------------
* Test.__dict__["start"]
<function start at 0x011E40F0>
18759920
* getattr(Test,"start")
<unbound method Test.start>
18725264
t.start --> <bound method Test.start of <__main__.Test instance at 0x011DB940>>
18725264
----------------------------------------------
* t.__dict__["start"]
KeyError : 'start'
* getattr(t,"start")
<bound method Test.start of <__main__.Test instance at 0x011DB940>>
18725264
我的意思是Python回答说,名为“start”
的t属性是Test.start,而不是t.start
因此,从t.start.\uuuu module\uuuu
是“\uu main\uuuu”
这一事实来看,在我看来,您可能认为t.start属于模块名称空间,因此您应该能够编写类似于getattr(obj,“func”)
的东西来获取对象start
但这是错误的。
在模块的全局名称空间=名称空间中找不到方法start(我编写该方法),因为它位于Test的名称空间中。作为一种方法,您必须通过实例、类或类本身来实现它
还有一件事。
我对方法进行了精确分析,因为我相信方法t.start基于一个函数,该函数与它不同,并且位于模块的名称空间中。实际上,方法是指向实例和此全局命名空间函数的指针包装器:
如果您仍然不了解方法的工作原理,请查看
实施或许可以澄清问题。当一个实例属性
如果引用的不是数据属性,则将搜索其类。如果
名称表示一个有效的类属性,它是一个函数对象,一个
方法对象是通过打包(指向)实例对象而创建的
和函数对象一起出现在一个抽象对象中:
这是方法对象。当使用
参数列表,从实例构造一个新的参数列表
对象和参数列表,并使用
这是一个新的参数列表
我想强调的是,似乎有一个函数(不是方法)存在于某个地方,方法就是基于这个函数的
我认为这个函数位于模块名称空间中,这就是为什么Test.\uu dict\uuu[“start”]
给出
而
getattr(Tes)
class Test:
def __init__(self, *args, **kwargs):
pass
def start(self):
pass
t = Test()
print 'getattr(t,"start")'
print getattr(t,"start")
# result is
getattr(t,"start")
<bound method Test.start of <__main__.Test instance at 0x011DF288>>
class Test:
def __init__(self, *args, **kwargs):
pass
def start(self):
pass
def func():
print 'this is a func and not a method!!!'
t = Test()
print '* globals()["func"]'
print globals()["func"]
print id(globals()["func"])
print "===================================="
print '* Test.__dict__["start"]'
print Test.__dict__["start"]
print id(Test.__dict__["start"])
print '----------------------------------------------'
print '* getattr(Test,"start")'
print getattr(Test,"start")
print id(getattr(Test,"start"))
print '----------------------------------------------'
print '* getattr(t,"start")'
print getattr(t,"start")
print id(getattr(t,"start"))
print "===================================="
print globals()
* globals()["func"]
<function func at 0x011C27B0>
18622384
====================================
* Test.__dict__["start"]
<function start at 0x011DEFB0>
18739120
----------------------------------------------
* getattr(Test,"start")
<unbound method Test.start>
18725304
----------------------------------------------
* getattr(t,"start")
<bound method Test.start of <__main__.Test instance at 0x011DF418>>
18725304
{'__builtins__': <module '__builtin__' (built-in)>,
'__package__': None,
't': <__main__.Test instance at 0x011DF418>,
'func': <function func at 0x011C27B0>,
'Test': <class __main__.Test at 0x011DC538>,
'__name__': '__main__',
'__doc__': None}
class Test:
def __init__(self, *args, **kwargs):
pass
def start(self):
pass
def func():
print 'this is a func and not a method!!!'
t = Test()
print 'func --->',func
print id(func)
print '\nobj = __import__(t.start.__module__) done\n'
obj = __import__(t.start.__module__)
print '* globals()["func"]'
print globals()["func"]
print id(globals()["func"])
print '* obj.__dict__["func"]'
print obj.__dict__["func"]
print "* getattr(obj, 'func')"
print getattr(obj, 'func')
print "* getattr(__import__('__main__'), 'func')"
print getattr(__import__('__main__'), 'func')
func ---> <function func at 0x011C2470>
18621552
obj = __import__(t.start.__module__) done
* globals()["func"]
<function func at 0x011C2470> # <== address in hexadecimal
18621552 # <== address in decimal
* obj.__dict__["func"]
<function func at 0x011C2470>
* getattr(obj, 'func')
<function func at 0x011C2470>
* getattr(__import__('__main__'), 'func')
<function func at 0x011C2470>
class Test:
def __init__(self, *args, **kwargs):
pass
def start(self):
pass
print 'Test.start -->',Test.start
print id(Test.start)
print '----------------------------------------------'
print '* Test.__dict__["start"]'
print Test.__dict__["start"]
print id(Test.__dict__["start"])
print '* getattr(Test,"start")'
print getattr(Test,"start")
print id(getattr(Test,"start"))
print '\n'
print 't.start -->',t.start
print id(t.start)
print '----------------------------------------------'
print '* t.__dict__["start"]'
try:
print t.__dict__["start"]
print id(t.__dict__["start"])
except KeyError as e:
print 'KeyError :',e
print '* getattr(t,"start")'
print getattr(t,"start")
print id(getattr(t,"start"))
Test.start --> <unbound method Test.start>
18725264
----------------------------------------------
* Test.__dict__["start"]
<function start at 0x011E40F0>
18759920
* getattr(Test,"start")
<unbound method Test.start>
18725264
t.start --> <bound method Test.start of <__main__.Test instance at 0x011DB940>>
18725264
----------------------------------------------
* t.__dict__["start"]
KeyError : 'start'
* getattr(t,"start")
<bound method Test.start of <__main__.Test instance at 0x011DB940>>
18725264