了解所有基类的实现

2024-05-16 21:42:48 发布

您现在位置:Python中文网/ 问答频道 /正文

问题:

我正在尝试用python为blender3d创建一个插件来模拟boids粒子系统,这个插件非常复杂,将从头开始。你知道吗

这是我第三次尝试为它设计可维护的代码结构。你知道吗

我试着提出pythonic设计,允许快速原型化不同种类的粒子相互作用,这样我就可以创建一个新的粒子实现,并让它与系统中的其他粒子相互作用。你知道吗

参见示例:

class ParticleSystem:
    def __init__(self):
        self.particles = []

    def add_particle(self, particle):
        self.particles.append(particle)

    def step_frame(self, speed):
        for p in self.particles:
            p.step(speed)


 class Particle:
    def __init__(self, system)
        self.location = Vector(0,0,0)
        self.system = system

    def step(speed):
        for particle in self.system.particles:
            #random interatcion formula
            self.location = particle.location + self.location


system = ParticleSystem()

p = Particle(system)
system.add_particle(p)

正如你所看到的,这是我最好的方法,但是当我有多类粒子,我必须把系统传递给粒子,然后再把粒子传递给系统时,它变得非常混乱。你知道吗

问题

有没有一种方法可以让我检测类实现的创建,比如:Class Baseball(Particle):,让系统类知道所有现有的类型,这样我就可以调用system.create_baseball(location)?你知道吗


Tags: self插件init系统defstep粒子location
1条回答
网友
1楼 · 发布于 2024-05-16 21:42:48

最简单的方法可能是使用Particle__subclasses__方法。你知道吗

你可以这样定义ParticleSystem

class ParticleSystem(object):

    def __init__(self):
        self.particles = []

    def create_particle(self, particle_type, location):
        if particle_type in (cls.__name__ for cls in Particle.__subclasses__()):
            p = eval(particle_type)(self)
            p.location = location
            self.particles.append(p)
        else:
            raise TypeError("{} is not a subclass of Particle".format(particle_type))

也就是说,避免让不同的类知道彼此的内部工作原理通常是个好主意。ParticleSystem真的需要知道Particle的所有子类吗(更好的是,每个粒子都需要知道它所在的系统吗?)?还是只需要一种简单的方法来实例化新的Particle对象?如果您只是需要后者,您可以使用simple factory method。你知道吗

注意:使用eval通常有点鲁莽,但是因为它受到in Particle.__subclasses__()条件的保护,所以应该可以。你知道吗

相关问题 更多 >