![](/img/trans.png)
[英]Python - difference between self.method, lambda: self.method() and self.method() on startup
[英]is it possible to overwrite “self” to point to another object inside self.method in python?
class Wrapper(object):
def __init__(self, o):
# get wrapped object and do something with it
self.o = o
def fun(self, *args, **kwargs):
self = self.o # here want to swap
# or some low level C api like
# some_assign(self, self.o)
# so that it swaps id() mem addr to self.o
return self.fun(*args, **kwargs) # and now it's class A
class A(object):
def fun(self):
return 'A.fun'
a = A()
w = Wrapper(a)
print type(w) # wrapper
print w.fun() # some operation after which I want to loose Wrapper
print a is w # this goes False and I'd like True :)
# so that this is the original A() object
有沒有辦法在 Python 中做到這一點?
在方法內賦值給self
只是將局部變量self
重新綁定到新對象。 通常,對裸名稱的賦值永遠不會改變任何對象,它只是重新綁定左側的名稱以指向右側的對象。
因此,您需要做的是修改self
指向的對象以匹配self.o
指向的對象。 這只有在A
和Wrapper
都是新式類並且它們都沒有定義__slots__
才有可能:
self.__class__ = self.o.__class__
self.__dict__ = self.o.__dict__
這將在 CPython 中工作,但我不確定其他 Python 實現。 即使在 CPython 中,這樣做也是一個糟糕的主意。
(請注意,代碼最后一行中的is
條件仍將是False
,但我認為這符合您的意圖。)
不,你不能。 這將需要通過引用傳遞。 您可以更改局部變量(更准確地說,參數) self
就好了,但是這樣做不會影響作為參數傳遞的引用來自的任何位置(例如您的w
)。
考慮到情況(隱式傳遞self
),甚至不可能應用通常的技巧(例如使用單元素列表和變異x[0]
)。 即使這樣的技巧會奏效(或者如果有更晦澀的黑客可以做到這一點),他們也會非常氣餒。 它與 Python 程序員習慣的一切背道而馳。 只需讓Wrapper
對象表現得好像它被替換(即,將所有內容轉發到self.o
)。 這不會使身份檢查成功,但它是迄今為止最簡單、最干凈和最易於維護的解決方案。
注意:為了試驗,有一個非標准且絕對不可移植的 PyPy 擴展可以做到這一點(完全替換一個對象): __pypy__.become
。 不用說,使用它是非常不明智的。 尋找另一個解決方案。
您已經覆蓋了自己,但更改僅在fun()中本地有效。 我添加了幾個打印輸出來試試:
def fun(self, *args, **kwargs):
print self, self.o
self = self.o # here want to swap
print self, self.o
輸出顯示原始Wrapper和A in self和self.o,然后是A和traceback,因為self.o在A類中無效。
<__main__.Wrapper object at 0xb77be38c> <__main__.A object at 0xb77be34c>
<__main__.A object at 0xb77be34c>
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/tmp/python-2803VQb.py", line 21, in <module>
print w.fun() # some operation after which I want to loose Wrapper
File "/tmp/python-2803VQb.py", line 8, in fun
print self, self.o
AttributeError: 'A' object has no attribute 'o'
改變自我和副作用是不好的。 為什么不直接在調用代碼中分配給w:
print w.fun() # some operation after which I want to loose Wrapper
w = a # Sure you will loose the Wrapper
print a is w # this goes False and I'd like True :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.