可以从Python中的另一个子类调用方法吗?

2024-06-25 05:39:15 发布

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

我正试图建立一个机器人行为的模拟。我有一个Robot父抽象类和一个正常运行的NormalRobot子类。我想构建一个FaultyRobot子类,可能带有类似于部分“并行”继承的东西

父类Robot有一个absactmove()方法,因为我希望所有Robot子类都能够用相同的名称move()调用

NormalRobot有一个功能方法move(),它模拟一个“转弯”,在指定方向上移动指定距离。(通过多次调用move()模拟多个“转弯”)

FaultyRobot还应该有一个move()方法,该方法与NormalRobot的move()几乎相同,只是在“转弯”开始时,它随机地有可能不移动和改变方向。显然,我可以通过编写随机性代码(我在助手方法turn_is_faulty())并复制粘贴NormalRobot的move()的内容来做到这一点。但显然,这是一个不好的etiquete有重复的代码。Python继承使得从父类Robot继承move()方法非常容易,但是我需要从并行子类NormalRobot继承move()

我想象代码看起来像

def Class FaultyRobot:
    def move(self):
        if self.turn_is_faulty():
            self.set_robot_direction(360 * random.random())
        else:
            #call the NormalRobot move() 


Python是否允许某种部分“并行”继承


Tags: 方法代码selfmoveisdefrobotrandom
3条回答

我会说“有故障的机器人”只是一个“正常的机器人”,几乎没有故障

import numpy as np

class NormalRobot():
  def __init__(self, x):
    self.x = x
  def move(self, d):
    self.x += d

  def __repr__(self):
    return f"Position: {self.x}"
  
class FaultyRobot(NormalRobot):
  def __init__(self, x, is_faulty=True):
    self.x = x
    self.is_faulty = is_faulty

  def turn_is_faulty(self):
    return self.is_faulty

  def move(self, d):
    if self.turn_is_faulty():
      self.x += np.random.random()
    else:
      super().move(d)

测试:

n = NormalRobot(0)
f = FaultyRobot(0)
nf = FaultyRobot(0, False)

n.move(10)
nf.move(10)
f.move(10)

print (n, nf, f)

输出:

Position: 10 Position: 10 Position: 0.07103605819788694

您可以将共享功能放入mixin类中

import random                                 
                                     
class AbstractRobot:
    """My 1 dimensional robot"""
    def __init__(self, start_at):
        self.pos = start_at
    
class RobotMoveMixin:

    def move(self, delta):
        self.pos += delta
        print('moved to', self.pos)

class GoodRobot(RobotMoveMixin, AbstractRobot):
    pass
    
class BadRobot(RobotMoveMixin, AbstractRobot):

    def move(self, delta):
        print("bad robot")
        if random.choice((True, False)):
            super().move(delta)

robot = BadRobot(0)
for _ in range(10):
    robot.move(3)

现在好机器人和它的继承者得到了好的动作,而坏机器人和它的干涉者得到了混乱的动作

谢谢大家的帮助。我最终找到了另一个我认为可能很有趣的解决方案,所以我发布了它。我的解决方案在任何形式上都不使用继承,所以我怀疑你们中的一些人可能想到过类似的东西,但没有发布,因为它似乎与我问题的措辞相去甚远。这是我自己的问题,因为我认为这是继承的问题,所以我认为解决方案会有更好的继承结构。谢天谢地,有一个简单的解决办法

def Class FaultyRobot:
    def move(self):
        if self.turn_is_faulty():
            self.set_robot_direction(360 * random.random())
        else:
            StandardRobot.move(self)

Python确实允许在定义新子类的move()时调用一个子类的move()

相关问题 更多 >