Skip to main content
 首页 » 编程设计

python之方法的 "self"参数是否受到某种保护

2025年05月04日10dflying

编辑:

我的疑惑解开了,谢谢。
我不会重温我对隐藏在线程和多进程复杂性中的一个非常简单的概念的困惑,我只会陈述我的困惑的根源,以及对它的简单答案。
我想: self 是由 __init__() 创建的,因此 self 在 __init__() 的范围内.
实际上:self是在调用__init__()之前创建的,并且是在的“parent”作用域中创建的>__init__()。所以,self实际上是一个传递给__init__()的变量。总之,self 没有受到保护,也没有什么特别之处。

我在下面发布的代码是对涉及由另一个进程运行的线程的变量作用域的研究。虽然它不再与问题相关,但它确实挑战了你对 python 作用域的理解:self=10 # comment out this assignment and see what happens in def thread_WITHOUT_SelfPassedToIt( ):。再次感谢。

import threading 
import multiprocessing 
from time import sleep 
 
class exe_classBased(multiprocessing.Process): 
    def __init__(self): 
        super().__init__() 
        self.aaa = 'aaa' 
 
        self = 10 
 
 
    def run(self): 
 
        print( 
            '===================================================\n' 
            '<Round 0> self is NOT alterred in the scope of run()\n' 
            '===================================================' 
        ) 
 
        print('self in the start of run() ==>',type(self)) 
 
        def thread_WITHOUT_SelfPassedToIt(): 
            try: 
                print('in a thread WITHOUT self passed to it, self==>', type(self)) 
            except Exception as e: 
                print(e) 
            try: 
                print('self.aaa==',self.aaa) 
            except Exception as e: 
                print(e) 
 
            self=10 # comment out this assignment and see what happens 
             
 
        def thread_WITH_SelfPassedToIt(self): 
            print('in a thread WITH self passed to it, self==>', type(self)) 
            try: 
                print('self.aaa==',self.aaa) 
            except Exception as e: 
                print(e) 
 
        t = threading.Thread( 
            target=thread_WITHOUT_SelfPassedToIt, 
            daemon=1, 
        ) 
        t.start() 
 
        t = threading.Thread( 
            target=thread_WITH_SelfPassedToIt, 
            args=(self,), 
            daemon=1, 
        ) 
        t.start() 
 
        print( 
            '===================================================\n' 
            '<Round 1> self is ALTERRED in the scope of run()\n' 
            '===================================================' 
        ) 
 
        self=10 
 
 
        print('in the immidiate start of run() after self=10, self==>', type(self)) 
 
        def thread_WITHOUT_SelfPassedToIt1(): 
            nonlocal self 
            try: 
                print('in a thread WITHOUT self passed to it, self==>', type(self)) 
            except Exception as e: 
                print(e) 
 
            self=11 
 
        def thread_WITH_SelfPassedToIt1(self): 
            print('in a thread WITH self passed to it, self==', self) 
            try: 
                print('self.aaa==', self.aaa) 
            except Exception as e: 
                print(e) 
 
        t = threading.Thread( 
            target=thread_WITHOUT_SelfPassedToIt1, 
            daemon=1, 
        ) 
        t.start() 
 
        sleep(1) 
        # give the thread_WITHOUT_SelfPassedToIt enough time to have self=11 excecuted 
 
        t = threading.Thread( 
            target=thread_WITH_SelfPassedToIt1, 
            args=(self,), 
            daemon=1, 
        ) 
        t.start() 
 
        sleep(5) 
 
if __name__ == '__main__': 
    multiprocessing.freeze_support() 
    e = exe_classBased() 
    e.daemon = 1 
    e.start() 
    sleep(5) 
 
''' 
output: 
=================================================== 
<Round 0> self is NOT alterred in the scope of run() 
=================================================== 
self in the start of run() ==> <class '__mp_main__.exe_classBased'> 
local variable 'self' referenced before assignment 
local variable 'self' referenced before assignment 
in a thread WITH self passed to it, self==> <class '__mp_main__.exe_classBased'> 
self.aaa== aaa 
=================================================== 
<Round 1> self is ALTERRED in the scope of run() 
=================================================== 
in the immidiate start of run() after self=10, self==> <class 'int'> 
in a thread WITHOUT self passed to it, self==> <class 'int'> 
in a thread WITH self passed to it, self== 11 
'int' object has no attribute 'aaa' 
''' 

请您参考如下方法:

self 是该函数中的局部变量。重新分配它对程序的其余部分没有任何影响。这与在其他函数中分配参数变量没有什么不同,例如

def add1(x): 
    y = x + 1 
    x = 10 
    return y 
 
foo = 3 
bar = add1(foo) 
print(foo) 

这将打印 3,而不是 10,因为分配是 add1 的本地分配。