pythonの組み込み関数getattr()の紹介と例

2942 ワード

pythonの公式ドキュメントでは、getattr()の説明は次のとおりです.

getattr(object, name[, default])

Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object's attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.

属性名に基づいてオブジェクト値を返します.「name」がオブジェクト属性の名前である場合、対応する属性の値が返されます.

'# -*- coding: utf-8 -*-'

__author__ = 'lucas'

class attrtest(object):

  def __init__(self):
    pass

  def trygetattr0(self):
    self.name = 'lucas'
    print self.name
    #equals to self.name
    print getattr(self,'name')

  def attribute1(self,para1):
    print 'attribute1 called and '+ para1+' is passed in as a parameter'

  def trygetattr(self):
    fun = getattr(self,'attribute1')
    print type(fun)
    fun('crown')

if __name__=='__main__':
  test = attrtest()
  print 'getattr(self,\'name\') equals to self.name '
  test.trygetattr0()
  print 'attribute1 is indirectly called by fun()'
  test.trygetattr()
  print 'attrribute1 is directly called'
  test.attribute1('tomato')

このコードの実行結果は次のとおりです.

getattr(self,'name') equals to self.name 
lucas
lucas
attribute1 is indirectly called by fun()

attribute1 called and crown is passed in as a parameter
attrribute1 is directly called
attribute1 called and tomato is passed in as a parameter

Process finished with exit code 0

最初の関数tryattribute 0()は定義のようによく理解されています.2番目の関数tryattribute 1()は少し分かりにくいです.実は原理は複雑ではありません.funのtypeはinstancemethodであることがわかります.ここでは、関数に対してgetattr()の戻り値はポインタであり、ポインタはそれを受け入れる変数に値を与え、後でcallという変数は呼び出し変数が指す関数に等しいと考えられます.
原理は分かりましたが、getattrの役割は何ですか?
Javaやc#の反射に詳しいですか?反射の重要な役割の1つは、遅延負荷であり、これによりデカップリングが可能になり、システムをより効率的に動作させることができる.動的言語としてpythonは明らかにこの点でより強く、
getattr()はpython反射を実現するブロックであり,setattr(),dir()などの他の方法と組み合わせて,多くの興味深いことをすることができる.
次のシーンを見てみましょう.
1.あるクラスに他のクラスのメソッドを動的に追加する必要があります.

#   A      :
def addnewattributesfromotherclass(self,class_name):
    func_names = dir(class_name)
    for func_name in func_names:
      if not func_name.startswith('_'):
        new_func = getattr(class_name,func_name)
        self.__setattr__(func_name,new_func())

必要なのは

a = A()

b = B()

a.addnewattributesfromotherclass(b)

これによりaはBの「非プライベート」メソッドを呼び出すことができる.