21

したがって、このコード:

from inspect import *

class X(object):
  def y(self):
    pass

methods = getmembers(X, predicate=ismethod)
functions = getmembers(X, predicate=isfunction)

print("%r" % methods)
print("%r" % functions)

python2.7から得られるもの:

[('y', <unbound method X.y>)]
[]

そして python3.3 から得られるもの:

[]
[('y', <function X.y at 0x1006ee3b0>)]

私は鼻を鳴らしましたが、この動作の変化の明らかな理由はわかりません。

具体的には、python 3 が私のメソッドを関数として扱うのはなぜですか?

クラスのメソッドのリストを取得するクロスランタイムの方法はありますか?

(つまり、python2.X と 3.X の両方で実行したときに同じものを返すもの)

編集: getmembers() が機能しない例:

from inspect import *

class X(object):
  def y(self):
    pass

methods = getmembers(X)
for i in methods:
  if ismethod(i):
    print("Method: %s" % str(i))
  else:
    print("Not a method: %s" % str(i))

版画:

Not a method: ('__class__', <attribute '__class__' of 'object' objects>)
Not a method: ('__delattr__', <slot wrapper '__delattr__' of 'object' objects>)
Not a method: ('__dict__', <attribute '__dict__' of 'X' objects>)
Not a method: ('__dir__', <method '__dir__' of 'object' objects>)
Not a method: ('__doc__', None)
Not a method: ('__eq__', <slot wrapper '__eq__' of 'object' objects>)
Not a method: ('__format__', <method '__format__' of 'object' objects>)
Not a method: ('__ge__', <slot wrapper '__ge__' of 'object' objects>)
Not a method: ('__getattribute__', <slot wrapper '__getattribute__' of 'object' objects>)
Not a method: ('__gt__', <slot wrapper '__gt__' of 'object' objects>)
Not a method: ('__hash__', <slot wrapper '__hash__' of 'object' objects>)
Not a method: ('__init__', <slot wrapper '__init__' of 'object' objects>)
Not a method: ('__le__', <slot wrapper '__le__' of 'object' objects>)
Not a method: ('__lt__', <slot wrapper '__lt__' of 'object' objects>)
Not a method: ('__module__', '__main__')
Not a method: ('__ne__', <slot wrapper '__ne__' of 'object' objects>)
Not a method: ('__new__', <built-in method __new__ of type object at 0x1001e0640>)
Not a method: ('__reduce__', <method '__reduce__' of 'object' objects>)
Not a method: ('__reduce_ex__', <method '__reduce_ex__' of 'object' objects>)
Not a method: ('__repr__', <slot wrapper '__repr__' of 'object' objects>)
Not a method: ('__setattr__', <slot wrapper '__setattr__' of 'object' objects>)
Not a method: ('__sizeof__', <method '__sizeof__' of 'object' objects>)
Not a method: ('__str__', <slot wrapper '__str__' of 'object' objects>)
Not a method: ('__subclasshook__', <method '__subclasshook__' of 'object' objects>)
Not a method: ('__weakref__', <attribute '__weakref__' of 'X' objects>)
Not a method: ('y', <function X.y at 0x1006ee3b0>)
4

2 に答える 2

22

特に違いはありませんinspectが、一般的にPython 3はこちらを参照してください

「バインドされていないメソッド」の概念は言語から削除されました。メソッドをクラス属性として参照すると、プレーンな関数オブジェクトが取得されるようになりました。

クロスプラットフォームに関する私の提案は次のとおりです。

getmembers(X, predicate=lambda x: isfunction(x) or ismethod(x))
于 2013-06-10T08:45:02.420 に答える
8

基本的に、関数とバインドされていないメソッドの間に違いはないためです。このバインドされていないメソッドの考え方は、主に歴史的な理由で Python 2 に存在し、Python 3 で削除されました。

BDFL 自身によるこの電子メールには、いくつかの詳細が記載されています。


更新された質問に答えます。inspect.isroutineバインドされていないメソッドと関数の両方に一致し、C で実装されたメソッド/関数にも一致するという追加の利点があるため、使用するのが最善だと思います。

inspect.getmembers必要に応じて出力をフィルタリングします。オプションのpredicateパラメーターも必要です。

于 2013-06-10T08:45:55.703 に答える