Python类多实例使用PyBullet时客户端的作用范围疑问
PyBullet 多实例共享问题解答
首先明确一个核心点:在Python中,模块导入是进程级别的单例机制。你在foo.py里写的import pybullet as p,不管你创建多少个Foo类的实例,这个p对象都是整个程序共享的——所有实例用的都是同一个PyBullet API引用,不存在“各自独有”的情况。
接下来结合你的代码具体分析:
- 当你创建
foo1时,__init__里调用p.connect(p.DIRECT),会创建一个物理客户端,返回的physicsClient是这个客户端的ID(比如默认是0),此时PyBullet的默认客户端就是这个ID为0的客户端。 - 当你再创建
foo2时,又调用了一次p.connect(p.DIRECT),这会创建第二个物理客户端(ID为1),同时PyBullet会把默认客户端切换成最新创建的这个ID为1的客户端。 - 这时候你调用
foo1.setGravity(),执行的p.setGravity(...)因为没有指定具体的客户端ID,会直接作用在当前默认的客户端(也就是foo2的那个),反而不会影响foo1自己的物理世界——这和你直觉里的“调用foo1的方法就影响foo1”完全相反。
要让每个Foo实例的操作只作用在自己的物理世界里,你需要把每个实例对应的客户端ID保存下来,并且在调用PyBullet API时显式指定这个ID:
修改后的foo.py代码:
import pybullet as p class Foo: def __init__(self, counter): # 保存当前实例的物理客户端ID self.physics_client_id = p.connect(p.DIRECT) def setGravity(self): # 调用API时指定客户端ID,确保作用在当前实例的物理世界 p.setGravity(0, 0, -9.81, physicsClientId=self.physics_client_id)
这样不管你创建多少个Foo实例,每个实例的setGravity都会精准作用在自己的物理客户端上,不会互相干扰。
内容的提问来源于stack exchange,提问作者FR_MPI




