[英]How can I explicitly see what 'self' does in python?
我在某處讀到在 Python 中使用 ' self ' 將myobject.method (arg1, arg2)
轉換為MyClass.method(myobject, arg1, arg2)
。
有誰知道我如何證明這一點? 只有當我使用dis.dis
查看字節碼時才有可能嗎?
self什么都不做。 self只是 Python 類定義中方法的第一個參數的常規名稱。 這個參數將傳遞一個類的實例。
從本質上講,要了解實際發生的情況,您必須了解 Python 描述符。 最好的地方是官方文檔歸結起來,描述符對象是實現__get__
、 __set__
或__delete__
。 這些方法攔截對象屬性訪問obj.x
、對象屬性賦值: obj.x = 42
和對象屬性刪除del obj.x
。
此外,請查看HOWTO ,其中展示了 Python 函數和方法如何簡單地使用描述符,並展示了一個 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__
方法,如果沒有實例調用則返回函數本身,或者返回綁定第一個參數的方法對象。
在 IDLE 中親自嘗試一下可以幫助你解決這個問題:
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 不轉換任何東西,它只是默默地將類實例作為第一個參數傳遞給類方法。 在上面你可以看到你是否將方法@staticmethod
靜態(通過@staticmethod
裝飾器),你避免了額外的參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.