2024-10-03 21:35:27 发布
网友
我在某个地方读到,在Python中使用'self'可以转换myobject.method (arg1, arg2) 变成MyClass.method(myobject, arg1, arg2)。你知道吗
myobject.method (arg1, arg2)
MyClass.method(myobject, arg1, arg2)
有人知道我怎么证明吗? 只有使用dis.dis查看字节码才有可能吗?你知道吗
dis.dis
在空闲时自己尝试一下可以帮你解决这个问题:
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),则可以避免使用额外的参数。你知道吗
@staticmethod
self什么都不做。self只是Python类定义中方法的第一个参数的常规名称。此参数将被传递给类的实例。你知道吗
本质上,要理解实际发生的事情,您必须理解Python描述符。最好的地方是官方的docs 简而言之,描述符对象是实现__get__、__set__或__delete__的对象。这些方法拦截对象属性访问、对象属性分配和对象属性删除。你知道吗
__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__方法,如果在没有实例的情况下调用该方法,则返回函数本身,或者返回绑定第一个参数的方法对象。你知道吗
在空闲时自己尝试一下可以帮你解决这个问题:
Python不转换任何东西,它只是默默地将类实例作为第一个参数传递给类方法。在上面,您可以看到,如果将方法设置为静态的(通过
@staticmethod
decorator),则可以避免使用额外的参数。你知道吗self什么都不做。self只是Python类定义中方法的第一个参数的常规名称。此参数将被传递给类的实例。你知道吗
本质上,要理解实际发生的事情,您必须理解Python描述符。最好的地方是官方的docs 简而言之,描述符对象是实现
__get__
、__set__
或__delete__
的对象。这些方法拦截对象属性访问、对象属性分配和对象属性删除。你知道吗另外,请查看HOWTO,其中显示了Python如何实现functions and methods are simply descriptors,并显示了一个Python实现示例(当然,在CPython中,这是用C实现的):
我们可以“欺骗”并创建我们自己的对象,只包装一个函数对象,然后看看这是否有效。你知道吗
或者,在REPL中:
这向您展示了“self”背后的魔力仅仅是函数对象是描述符,它们实现了一个
__get__
方法,如果在没有实例的情况下调用该方法,则返回函数本身,或者返回绑定第一个参数的方法对象。你知道吗相关问题 更多 >
编程相关推荐