如何明确地看到“self”在python中的作用?

2024-10-03 21:35:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我在某个地方读到,在Python中使用'self'可以转换myobject.method (arg1, arg2) 变成MyClass.method(myobject, arg1, arg2)。你知道吗

有人知道我怎么证明吗? 只有使用dis.dis查看字节码才有可能吗?你知道吗


Tags: self证明字节地方myclassmethoddisarg1
2条回答

在空闲时自己尝试一下可以帮你解决这个问题:

class MyObject(object):
  def method(self, arg1, arg2):
     print(self)

  @staticmethod
  def static_method(arg1, arg2):
     print(arg1)

my_object = MyObject()
my_object.method(1, 2)
>>> <MyObject at 0x1234>
my_object.static_method(1, 2)
>>> 1

Python不转换任何东西,它只是默默地将类实例作为第一个参数传递给类方法。在上面,您可以看到,如果将方法设置为静态的(通过@staticmethoddecorator),则可以避免使用额外的参数。你知道吗

self什么都不做。self只是Python类定义中方法的第一个参数的常规名称。此参数将被传递给类的实例。你知道吗

本质上,要理解实际发生的事情,您必须理解Python描述符。最好的地方是官方的docs 简而言之,描述符对象是实现__get____set____delete__的对象。这些方法拦截对象属性访问、对象属性分配和对象属性删除。你知道吗

另外,请查看HOWTO,其中显示了Python如何实现functions and methods are simply descriptors,并显示了一个Python实现示例(当然,在CPython中,这是用C实现的):

class Function(object):
    . . .
    def __get__(self, obj, objtype=None):
        "Simulate func_descr_get() in Objects/funcobject.c"
        if obj is None:
            return self
        return types.MethodType(self, obj)

我们可以“欺骗”并创建我们自己的对象,只包装一个函数对象,然后看看这是否有效。你知道吗

import types
class Function:
    def __init__(self, func):
        self._func = func
    def __call__(self, *args, **kwargs):
        return self._func(*args, **kwargs)
    def __get__(self, obj, objtype=None):
        "Simulate func_descr_get() in Objects/funcobject.c https://docs.python.org/3/howto/descriptor.html#functions-and-methods"
        if obj is None:
            return self
        else:
            return types.MethodType(self, obj)

class Foo:
   def __init__(self):
       self.foo = 42
   bar = Function(lambda self:
       self.foo ** 2

或者,在REPL中:

>>> import types
>>>
>>> class Function:
...     def __init__(self, func):
...         self._func = func
...     def __call__(self, *args, **kwargs):
...         return self._func(*args, **kwargs)
...     def __get__(self, obj, objtype=None):
...         "Simulate func_descr_get() in Objects/funcobject.c https://docs.python.org/3/howto/descriptor.html#functions-and-methods"
...         if obj is None:
...             return self
...         else:
...             return types.MethodType(self, obj)
...
>>> class Foo:
...    def __init__(self):
...        self.foo = 42
...    bar = Function(lambda self:
...        self.foo ** 2
...    )
...
>>> Foo().bar()
1764

这向您展示了“self”背后的魔力仅仅是函数对象是描述符,它们实现了一个__get__方法,如果在没有实例的情况下调用该方法,则返回函数本身,或者返回绑定第一个参数的方法对象。你知道吗

相关问题 更多 >