【发布时间】: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 怎么知道Worker 的work_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 假设
Worker在House上使用Paint。Worker失去energy_cost中指定的能量。House被绘制。稍后,我希望能够使用name和description,以便用户可以看到每个任务是什么以及做什么,然后使用该任务。
标签: python function object inheritance abstract-base-class