python类对象属性的问题

102 阅读2分钟

python项目中,在很多class实现的内容下,会生成一个类的对象实例。当有多个项目调用该对象实例时,是否可能发生调用冲突?如项目A给实例属性a赋值为1,而项目B给a赋值为2,然后A、B均错误的获得了对方的属性值。

测试代码

首先,我们在类文件中创建一个测试类ClassDemo,分别创建静态函数static_call和类函数call_test,分别测试。静态函数输出当前进程id,输入index。类函数分别输出。最后实例化变量class_demo。类文件如下:

import time, os


class ClassDemo:
    def __init__(self):
        self.value = 0

    @staticmethod
    def static_call(index):
        time.sleep(5)
        print("static method: ", index, os.getpid())

    def set_index(self, index):
        self.value = index
        time.sleep(index)
        print("set", index, os.getpid(), self.value, id(self), id(self.value))

    def get_index(self, index):
        time.sleep(6-index)
        print("get: ", index, os.getpid(), self.value, id(self), id(self.value))

    def __call__(self, index):
        self.set_index(index)
        self.get_index(index)


class_demo = ClassDemo()

创建五个进程,分别调用类函数和静态函数。测试函数内容如下:

from multiprocessing import Process
from test import class_demo

def test_case_assisstant1():
    process_list = []
    for i in range(5):
        process = Process(target=class_demo.call_test, args=(i,))
        process_list.append(process)
        process.start()

    for process in process_list:
        process.join()

    for i in range(5):
        process = Process(target=class_demo.static_call, args=(i,))
        process_list.append(process)
        process.start()

    for process in process_list:
        process.join()


if __name__ == "__main__":
    test_case_assisstant1()

结果输出如下。

set 0 1533197 0 140203350707984 8909768
set 1 1533198 1 140203350707984 8909800
set 2 1533201 2 140203350707984 8909832
set 3 1533202 3 140203350707984 8909864
set 4 1533204 4 140203350707984 8909896
get:  0 1533197 0 140203350707984 8909768
get:  2 1533201 2 140203350707984 8909832
get:  1 1533198 1 140203350707984 8909800
get:  3 1533202 3 140203350707984 8909864
get:  4 1533204 4 140203350707984 8909896

结论

从输出结果情况来看,可以得出如下结论:

  1. 多进程调用类函数时,各进程对类属性的改变不会相互冲突。
  2. 不论是类函数还是静态函数,多进程执行由系统调度,不保证执行顺序。
  3. 不同进程中调用的对象为同一对象,不同进程中类对象的变量value指向不同位置。