9

Python では「.」を使用できます。オブジェクトの辞書項目にアクセスするため。例えば:

class test( object ) :
  def __init__( self ) :
    self.b = 1
  def foo( self ) :
    pass
obj = test()
a = obj.foo

上記の例から、「a」オブジェクトを持っている場合、割り当てられた「foo」メソッドの親名前空間である「obj」への参照を取得することは可能ですか? たとえば、obj.b を 2 に変更するには?

4

3 に答える 3

17

バインドされたメソッドでは、次の 3 つの特別な読み取り専用パラメーターを使用できます。

  • (バインドされていない) 関数オブジェクトを返すim_func
  • 関数がバインドされているオブジェクトを返すim_self (クラス インスタンス)
  • im_selfのクラスを返すim_class

周りのテスト:

class Test(object):
    def foo(self):
        pass

instance = Test()
instance.foo          # <bound method Test.foo of <__main__.Test object at 0x1>>
instance.foo.im_func  # <function foo at 0x2>
instance.foo.im_self  # <__main__.Test object at 0x1>
instance.foo.im_class # <__main__.Test class at 0x3>

# A few remarks
instance.foo.im_self.__class__ == instance.foo.im_class # True
instance.foo.__name__ == instance.foo.im_func.__name__  # True
instance.foo.__doc__ == instance.foo.im_func.__doc__    # True

# Now, note this:
Test.foo.im_func != Test.foo # unbound method vs function
Test.foo.im_self is None

# Let's play with classmethods
class Extend(Test):
    @classmethod
    def bar(cls): 
        pass

extended = Extend()

# Be careful! Because it's a class method, the class is returned, not the instance
extended.bar.im_self # <__main__.Extend class at ...>

ここで注目すべき興味深い点があります。これは、メソッドがどのように呼び出されているかについてのヒントを提供します。

class Hint(object):
    def foo(self, *args, **kwargs):
        pass

    @classmethod
    def bar(cls, *args, **kwargs):
        pass

instance = Hint()

# this will work with both class methods and instance methods:
for name in ['foo', 'bar']:
    method = instance.__getattribute__(name)
    # call the method
    method.im_func(method.im_self, 1, 2, 3, fruit='banana')

基本的に、バインドされたメソッドのim_self属性が変更され、 im_funcを呼び出すときに最初のパラメーターとして使用できるようになります。

于 2009-06-05T06:31:40.190 に答える
14

Python 2.6+ (Python 3 を含む)

__self__バインドされたメソッドのプロパティを使用して、メソッドがバインドされているインスタンスにアクセスできます。

>> a.__self__
<__main__.test object at 0x782d0>
>> a.__self__.b = 2
>> obj.b
2

Python 2.2+ (Python 2.x のみ)

プロパティを使用することもできますim_selfが、これは Python 3 との前方互換性がありません。

>> a.im_self
<__main__.test object at 0x782d0>
于 2009-06-05T05:06:02.753 に答える
7

python2.6以降、それぞれim_selfim_funcare__self__との同義語__func__im*py3kでは属性は完全になくなりました。したがって、次のように変更する必要があります。

>> a.__self__
<__main__.test object at 0xb7b7d9ac>
>> a.__self__.b = 2
>> obj.b
2
于 2009-06-05T07:16:59.383 に答える