Pythonのdescriptor(2)


前文 に接続します。
 
前にdescriptorと言いましたが、これはJavaのsetterと似ています。しかし、このdescriptorと上記で述べた関数の方法はどういう関係がありますか?
 
すべての関数はdescriptorです。ゲットする方法
>>> def hello():
	pass

>>> dir(hello)
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__



', '__getattribute__', 
'__hash__', '__init__', '__module__', '__name__', '__new__', 
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_closure', 
'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
>>> 
 注意してください。関数のオブジェクトには、__()がありません。set_同前del_方法ですので、non-data descriptorです。
方法も実は関数です。
>>> class T(object):
	def hello(self):
		pass

>>> T.__dict__['hello']
<function hello at 0x00CD7EB0>
>>> 
 あるいは、方法を特殊な関数として見ることができます。ただし、それらはクラスに存在します。関数の属性を取得する時に戻ってくるのは、関数自体ではなく、関数自体です。ゲットする方法の戻り値は、次の種類Tの定義に続く。
>>> T.hello     T hello  ,      , T __dict__    ,    <function hello at 0x00CD7EB0>,       <function hello at 0x00CD7EB0>,    __get__  ,          __get__(None, T)   :  unbound  。


<unbound method T.hello>
>>> f = T.__dict__['hello']   #   T __dict__   hello,        ,     <function hello at 0x00CD7EB0>


>>> f
<function hello at 0x00CD7EB0>
>>> t = T()                 
>>> t.hello                     #       ,      <function hello at 0x00CD7EB0> __get__(t, T)   :  bound  。



<bound method T.hello of <__main__.T object at 0x00CDAD10>>
>>> 
 上記の説明を確認するために、次のコードを継続します。
>>> f.__get__(None, T)
<unbound method T.hello>
>>> f.__get__(t, T)
<bound method T.hello of <__main__.T object at 0x00CDAD10>>
 素晴らしいです
 
まとめてみます
      1.すべての関数には_u_があります。ゲットする方法
      2.関数がクラスの__u uにあるときdict_.において、この関数は、カテゴリまたはインスタンスを通して関数を取得する場合に、関数自体ではなく、その関数の__u u u u u_を返します。ゲットする方法は値を返します
 
私は誤解しているかもしれません。方法は関数です。特殊な関数です。実は方法と関数には違いがあります。正確に言えば、方法は方法で、関数は関数です。
>>> type(f)
<type 'function'>
>>> type(t.hello)
<type 'instancemethod'>
>>> type(T.hello)
<type 'instancemethod'>
>>> 
 関数はfunctionタイプで、methodはinstancementhodです。
unbound methodとbound methodについてもっと話してください。c実装では、それらは同じオブジェクトです。(それらは全部instancementhodタイプです。)まず、それらの中に何があるかを見てみます。
>>> dir(t.hello)
['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__get__', '__getattribute__', 
'__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', 
'__str__', 'im_class', 'im_func', 'im_self']
 __コールバックこれらは呼び出し可能なオブジェクトであり、推測もできます。コールバックの実装は、大まかには、他の関数(上のハローなど、私たちが望むどれか)を調整し、対象を第一パラメータとするべきです。
注意するのはim_ですクラスfunc,im_selfこれらのものはよく知らないです。T.helloの中で、それぞれT.helloとtを表します。これらがあると、どのように純粋なPythonがinstancementhodを実現するかを大体想像できます。
 
実はいくつかの内建関数がありますが、descriptorと関係があります。簡単に話してください。
 
classmethod
 
クラス方法の最初の暗黙的パラメータはクラス自体(一般的な方法の最初の暗黙的パラメータはインスタンス自体)であり、クラス方法はクラスから呼び出すことができ、インスタンスから呼び出すことができる。
>>> class T(object):
	def hello(cls):
		print 'hello', cls
	hello = classmethod(hello)   #    : hello      ,           hello

	
>>> t = T()
>>> t.hello()
hello <class '__main__.T'>
>>> T.hello()
hello <class '__main__.T'>
>>> 
 注意:classmethodはクラスで、関数ではありません。classmethod類は_uがありますゲットする方法は、だから、上のt.helloとT.helloが獲得されたのは、実際にはclassimethodの_u uです。ゲットするメソッドの戻り値
>>> t.hello
<bound method type.hello of <class '__main__.T'>>
>>> type(t.hello)
<type 'instancemethod'>
>>> T.hello
<bound method type.hello of <class '__main__.T'>>
>>> type(T.hello)
<type 'instancemethod'>
>>> 
 上からは、t.helloとT.helloはinstancomthodタイプで、Tに結び付けられていることが分かります。つまりclassimethodの_uです。ゲットする方法はinstancenmethodオブジェクトを返します。前のinstancenmethodの分析から、t.helloのim_selfはTで、im_classはtype(Tはtypeの例)で、im_funcは関数helloです
>>> t.hello.im_self
<class '__main__.T'>
>>> t.hello.im_class
<type 'type'>
>>> t.hello.im_func
<function hello at 0x011A40B0>
>>> 
 完全一致ですだから、純粋なPythonのclassmethodを実現するのも難しくないです。)
 
staticmethod
 
staticmethodは関数を静的方法に変換でき,静的方法には暗黙的な最初のパラメータがない。
class T(object):
	def hello():
		print 'hello'
	hello = staticmethod(hello)

	
>>> T.hello()   #          
hello
>>> T.hello
<function hello at 0x011A4270>
>>> 
 T.ハローは直接関数を返しました。staticmethod類の_u u uを予想します。ゲットする方法としては、直接に対象自体に戻ります。
 
もう一つのpropertyは上の二つと同じです。data descripterです。