【发布时间】:2017-04-11 18:46:56
【问题描述】:
我正在尝试复制 Java 库的 API 以解决车辆路线问题,它突出显示了我对 Python 类不了解的内容。
车队可以分为两个基本标准;第一个是您拥有的车辆类型(例如VehicleType 定义容量、运行成本等)和单个车辆(Vehicle 具有不同的班次模式等)。
在我的简化示例中,我想定义一个VehicleType,然后定义一个Vehicle,它将VehicleType 的属性传递给构造函数。按照 Lennart here 的回答,在一般情况下使用 __getattr__ 效果很好。但是,假设我有一个司机,他驾驶 50 辆货车中的一辆,具有携带危险物品的特殊资格,所以我想在 Vehicle 实例上添加一个额外的容量属性。我尝试了以下方法:
class VehicleType(object):
def __init__(self, fixed_cost=0, cost_per_distance=0, cost_per_time=0):
self.capacities = {}
self.fixed_cost = fixed_cost
self.cost_per_distance = cost_per_distance
self.cost_per_time = cost_per_time
def add_capacity_dimension(self, dimension_id, dimension_size):
""" Define a package type and how many of them this vehicle type can carry """
self.capacities[dimension_id] = dimension_size
class Vehicle(object):
def __init__(self, vehicle_type=None, identifier=None):
self._vehicle_type = vehicle_type
self.identifier = identifier
def add_capacity_dimension(self, dimension_id, dimension_size):
self.capacities[dimension_id] = dimension_size
def __getattr__(self, name):
return getattr(self._vehicle_type, name)
if __name__ == '__main__':
van_type = VehicleType()
van_type.add_capacity_dimension("general items", 34)
special_van = Vehicle(vehicle_type=van_type)
special_van.add_capacity_dimension("hazardous chemicals", 50)
print("Capacities of special van: {}".format(special_van.capacities))
print("Capacity of van_type: {}".format(van_type.capacities)) # Why?
我不明白为什么我的方法也影响了capacities 的van_type。 Vehicle 不直接继承自 VehicleType,我在 Vehicle 类中定义了 add_capacity_dimension。这也与我对the docs 对__getattr__ 的理解相矛盾:
当属性查找没有找到属性中的属性时调用 通常的地方(即它不是实例属性,也不是在 自我的类树)。 name 是属性名。
有人能解释一下为什么实例van_type也在这里受到影响吗?
【问题讨论】:
-
这其中的哪一部分让您感到惊讶?你对
van_type有一个capacities感到惊讶吗?你对它的变异感到惊讶吗? -
@user2357112 你是对的,我错过了链接,因为看起来太长了。
capacitiesforVehicle本身需要__getattr__。在这种情况下,这样做的唯一方法是在Vehicle中定义capacities,然后将__getattr__用于其余属性? -
@roganjosh 他们将匹配。如果他们不这样做,那么您的 MCVE 是错误的。
-
@wim MCVE 是正确的,我在尝试编写时验证了
id()错误。再次检查。谢谢大家,对于时刻感到抱歉。
标签: python python-2.7