zl程序教程

您现在的位置是:首页 >  后端

当前栏目

python中的内置函数getattr()介绍及示例

Python 函数 介绍 示例 内置 getattr
2023-06-13 09:15:38 时间

在python的官方文档中:getattr()的解释如下:

getattr(object,name[,default])

Returnthevalueofthenamedattributeofobject.namemustbeastring.Ifthestringisthenameofoneoftheobject"sattributes,theresultisthevalueofthatattribute.Forexample,getattr(x,"foobar")isequivalenttox.foobar.Ifthenamedattributedoesnotexist,defaultisreturnedifprovided,otherwiseAttributeErrorisraised.

根据属性名称返回对象值。如果“name”是对对象属性的名称,则返回对应属性的值。

"#-*-coding:utf-8-*-"

__author__="lucas"

classattrtest(object):

def__init__(self):
pass

deftrygetattr0(self):
self.name="lucas"
printself.name
#equalstoself.name
printgetattr(self,"name")

defattribute1(self,para1):
print"attribute1calledand"+para1+"ispassedinasaparameter"

deftrygetattr(self):
fun=getattr(self,"attribute1")
printtype(fun)
fun("crown")

if__name__=="__main__":
test=attrtest()
print"getattr(self,\"name\")equalstoself.name"
test.trygetattr0()
print"attribute1isindirectlycalledbyfun()"
test.trygetattr()
print"attrribute1isdirectlycalled"
test.attribute1("tomato")

 这段代码执行的结果是:

getattr(self,"name")equalstoself.name
lucas
lucas
attribute1isindirectlycalledbyfun()
<type"instancemethod">
attribute1calledandcrownispassedinasaparameter
attrribute1isdirectlycalled
attribute1calledandtomatoispassedinasaparameter

Processfinishedwithexitcode0

第一个函数tryattribute0()非常好理解,就如同定义里说的一样。第二个函数tryattribute1()就有一点费解了。其实原理并不复杂,我们看到fun的type是instancemethod,这里你可以认为:对于函数,getattr()的返回值是一个指针,指针赋值给接受它的变量,以后call这个变量就等于调用变量指向的函数。

原理我们知道了,那getattr的作用是什么呢?

你熟悉java或者c#中的反射么?反射的一个重要作用就是延迟加载,这样可以解耦,这样可以让系统运行的更有效率。作为动态语言,python显然在这方面要更加强大,

getattr()就是实现python反射的一块积木,结合其它方法如setattr(),dir()等,我们可以做出很多有趣的事情。

我们看以下场景:

1.我需要在一个类中动态添加其它类中有的方法:

#如果类A中有如下方法:
defaddnewattributesfromotherclass(self,class_name):
func_names=dir(class_name)
forfunc_nameinfunc_names:
ifnotfunc_name.startswith("_"):
new_func=getattr(class_name,func_name)
self.__setattr__(func_name,new_func())

我们只需要:

a=A()

b=B()

a.addnewattributesfromotherclass(b)

这样a就可以调用B中的"非私有"方法啦。