【问题标题】:How can I make a class use a function that takes properties from another class?如何让一个类使用从另一个类获取属性的函数?
【发布时间】:2018-07-08 02:49:50
【问题描述】:

我试图让一个类使用另一个类的函数,该函数使用另一个类的属性。

这里是详细的问题:

假设我们有一个名为Worker 的基类。每个Worker 都想在House 上工作。每个Worker 都有一个Tasks 列表,可以从中选择并完成。每个Task 都有一个name、一个description、一个energy_cost 来完成任务,它还有一个do_task 函数,允许Worker 实际执行任务。

以下是我们在代码中的表示方式:

from abc import ABC, abstractmethod

class House(object): #The object a worker works on
    pass 

#Tasks start here   

class Task(ABC):

    @property
    @abstractmethod
    def name(self):
        pass

    @property
    @abstractmethod
    def description(self):
        pass

    @property
    @abstractmethod
    def energy_cost(self):
        pass

    @abstractmethod
    def do_task(self):
        pass


class Paint(Task):
    name = "Paint"
    description = "Paint a house partially"
    energy_cost = 20

    def do_task(self, house):
        #paint house here


class Slosh(Task):
    name = "Slosh"
    description = "Completely cover a house in paint"
    energy_cost = 40

    def do_task(self, house):
        #slosh house here

#Worker classes

class Worker(object):

    def __init__(self):
        self.energy = 100
        self.current_task = None

    def set_task(self, task):
        self.current_task = task

    def work(self, house):
        self.energy -= self.current_task.energy_cost
        self.current_task.do_task(house)


class Painter(Worker):

    def __init__(self):
        self.task_list = [Paint, Slosh]
        super().__init__()

但是如果我们需要访问Worker 的属性之一以执行Task 呢?假设Worker 有一个名为work_speed 的属性,它指定了任务完成的速度。 Task 怎么知道Workerwork_speed 是什么?我们可以像这样将Worker 实例传递给Worker 的task_list 中的Task 实例:

self.task_list = [Paint(self), Slosh(self)]

但这很笨拙,而且似乎也非常不必要。

我们也可以在Worker的类定义中继承每个Task,但我们不需要额外的属性,如果我们有多个Tasks,do_task方法将被覆盖。

理想情况下,Worker 应该能够以worker.do_task() 的形式执行Task,以便do_task 可以访问Worker 的属性,并且它应该能够使用像@ 这样的属性987654353@ 定义在 Task 对象内。

我们将如何去做?

【问题讨论】:

  • 你能举一个预期功能的例子吗?
  • @Primusa 假设WorkerHouse 上使用PaintWorker 失去energy_cost 中指定的能量。 House 被绘制。稍后,我希望能够使用namedescription,以便用户可以看到每个任务是什么以及做什么,然后使用该任务。

标签: python function object inheritance abstract-base-class


【解决方案1】:

为什么不将您的担忧分开;与您在工人的工作职能中执行的工人有关的任何事情?

这往往是我的方法,如果您需要访问该工人的速度、当前能量等,请在该工人的工作函数中进行。

在您提出的示例中,如果我走这条路,我将创建一个通用的 Worker 超类,不同类型的 Worker 将继承该超类。

然后在 Worker 超类中我会做这样的事情:

class Worker():
"""The worker superclass, all workers inheirit from this"""
def work(self):
    """Perform the required task if any, deduct costs, if any, as necessary"""

    if self.current_task is not  None:
        if all(self.energy, self.current_task.energy_cost): self.energy -= self.current_task.energy_cost
        if all(self.money, self.current_task.monetary_cost): self.money -= self.current_task.monetary_cost
        if all(self.workspeed, self.current_task.duration): time.sleep(self.current_task.duration/self.workspeed)
        if self.current_task.do_task: self.current_task.do_task()

然后,您可以随意向子类添加属性,前提是您在超类中有一个案例。否则,您可以为每个子类编写一个方法,并在每个特殊情况之前/之后调用 super().work(),但数据处理完全取决于您。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    • 2023-01-20
    • 1970-01-01
    • 2019-05-25
    • 2018-03-15
    • 1970-01-01
    相关资源
    最近更新 更多