为了账号安全,请及时绑定邮箱和手机立即绑定

了解所有基类的实现

了解所有基类的实现

回首忆惘然 2021-05-21 19:02:15
问题:我正在尝试使用python模拟Boids粒子系统,这是我为Blender 3D创建的插件,这相当复杂,将从头开始。这是我第三次尝试为其设计可维护的代码结构。我试图提出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)?
查看完整描述

1 回答

?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

可能最简单的方法是使用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对象?如果仅需要后者,则可以使用简单的工厂方法。


注意:使用eval通常有点鲁ck,但由于它受到in Particle.__subclasses__()条件的保护,所以我们应该没事。


查看完整回答
反对 回复 2021-05-25
  • 1 回答
  • 0 关注
  • 116 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信