为什么Python中不同的类实例有相同的id?

iko*_*ool 0 python multithreading

我尝试在多线程中获取一个类的不同实例,但是 id(instance) 随机重新调整了相同的 id,即使我添加睡眠时间,这种情况仍然会发生,为什么?

#!/usr/bin/python
# coding=utf-8

import random
import threading

class Foo():
    def __init__(self):
        self.num = random.randrange(10000)

    def __str__(self):
        return "rand num is {}".format(self.num)

def getInatance():
    if lock.acquire():
        f = Foo()
        print(id(f), f)
        lock.release()

lock = threading.Lock()
if __name__ == "__main__":
    for x in range(10):
        th = threading.Thread(target=getInatance)
        th.start()

    for th in threading.enumerate():
        if th is not threading.current_thread():
            th.join()

# 2384808866048 rand num is 357
# 2384808640128 rand num is 7143
# 2384808640128 rand num is 900
# 2384808640128 rand num is 3260
# 2384808640032 rand num is 8161
# 2384808640032 rand num is 8573
# 2384808640080 rand num is 6300
# 2384808640080 rand num is 3476
# 2384808640128 rand num is 8112
# 2384808640128 rand num is 7357
Run Code Online (Sandbox Code Playgroud)

nos*_*nos 6

id(f)仅保证为您提供当前活动的所有对象中唯一的 id。但您的代码是结构化的,因此不太可能有多个Foo实例同时处于活动状态。

您的getInatance()函数会序列化创建Foo实例,一旦getInatance()函数返回,Foo您创建的实例就会被销毁,并且您创建的下一个对象可能会获得与不再存在的先前对象相同的 id。

如果您添加sleep()如下所示的 a,您更有可能看到唯一的对象 ID。(但仍然不能保证 - 请记住添加 sleep() 来修复明显的多线程问题是错误的)。

def getInatance():
    if lock.acquire():
        f = Foo()
        print(id(f), f)
        lock.release()
    time.sleep(1)
Run Code Online (Sandbox Code Playgroud)