__getattr__意外地更新了非继承类的实例

时间:2017-04-11 18:46:56

标签: python python-2.7

我正在尝试复制Java库的API以解决车辆路径问题,并且突出显示了我对Python类不了解的内容。

车队可以分为两个基本标准;第一个是您拥有的车辆类型(=> msg定义容量,运行成本等的实例)和个别车辆(VehicleType具有不同的换档模式等)。

在我的简化示例中,我想定义一个Vehicle,然后定义一个VehicleType,它将传递给构造函数的Vehicle的属性。根据Lennart here的回答,使用VehicleType在一般情况下完美无缺。但是,想象一下,我有50辆中有一辆面包车的驱动程序具有特殊资格来携带危险物品,因此我想在 __getattr__ 实例上添加额外的容量属性。我尝试了以下方法:

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? 的{​​{1}}。 capacities并非直接从van_type继承,我在Vehicle类中定义了VehicleType。这也与我对the docs关于add_capacity_dimension

的理解相矛盾
  

当属性查找未找到属性时调用   通常的地方(即它不是一个实例属性,也没有找到   自我的类树。 name是属性名称。

有人可以解释为什么实例Vehicle也会受到影响吗?

1 个答案:

答案 0 :(得分:2)

Vehicle个实例没有“capacity”属性。

self.capacities {来自special_van实施中)的Vehicle.add_capacity_dimension属性查询不是通过Vehicle解决,而是VehicleType通过自定义解析__getattr__

因此,special_van.capacitiesvan_type.capacities是同一个词。