これは、pythonの堅牢な機能でもあります。
イントロスペクションは、オブジェクト指向の言語で記述されたプログラムが実行時に認識できるオブジェクトのタイプです。単純な文は、実行時に取得できるオブジェクトのタイプです。type()、dir()、getattr()、hasattr()、isinstanceなど。 ()。
a =[1,2,3]
b ={'a':1,'b':2,'c':3}
c = True
print type(a),type(b),type(c) # <type 'list'><type 'dict'><type 'bool'>
print isinstance(a,list) # True
リフレクションメカニズムは、実行時にオブジェクトのタイプを動的に決定し、オブジェクトのプロパティ、メソッドを呼び出し、文字列を介してモジュールをインポートすることです。これは、文字列ベースのイベント駆動型です。
def hasattr(*args,**kwargs): # real signature unknown
"""
Return whether the object has an attribute with the given name.
This is done by calling getattr(obj, name) and catching AttributeError."""
pass
ソースコードのコメントから、オブジェクトに指定された名前の属性があるかどうかが返されることがわかります。そして、getattrを呼び出し、AttributeError例外をキャッチすることによって判断されます。上記の属性呼び出しと同様に、hasattr(a、 "test")を使用して判断できます。また、ソースコードのコメントから考えることもできます。evalもこのメソッドを実装できますか?
def has_attr(obj, name):try:eval("obj.%s()"% name)return True
except AttributeError as e:return False
a =Base()ifhas_attr(a,"test"):eval("a.test()")
# 出力:
Base
test
test
しかし、このメソッドには欠陥があります。これは、test()を2回呼び出すため、testが2回出力されるためです。これは、必要なものと同じではありません。 hasattrを使用する場合、この関数は判断で一度も呼び出されません。
属性が存在するかどうかを判断する関数を使用するには、属性を取得する関数が必要です。
def getattr(object, name,default=None): # known special caseof getattr
"""
getattr(object, name[,default])-> value
Get a named attribute from an object;getattr(x,'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case."""
pass
ソースコードのコメントから、オブジェクトオブジェクトのnameという名前の属性が取得されていることがわかります。デフォルトのパラメータがobject.nameで指定されている場合、属性が存在しない場合はデフォルト値が返されます。上記の例も同じです。
a =Base()ifhasattr(a,"test"):
func =getattr(a,"test")func()
# 出力:
Base
test
例から、hasattrがテスト関数を呼び出さず、getattrが取得したのは関数オブジェクトであり、それを呼び出さなかったことがわかります。a.test()関数は、func()のアクティブな実行を通じて実行され、 execとevalははるかに柔軟です。
プロパティの判断と取得が行われるため、プロパティの設定も必要です。
def setattr(x, y, v): # real signature unknown; restored from __doc__
"""
Sets the named attribute on the given object to the specified value.setattr(x,'y', v) is equivalent to ``x.y = v''"""
pass
Recommended Posts