[英]__getattr__ unexpectedly updates instance of a non-inherited class
我正在尝试针对车辆路径问题复制Java库的API,并着重强调了我对Python类不了解的一些知识。
车队可以分为两个基本标准: 第一种是您拥有的车辆类型(用于定义容量,运行成本等的VehicleType
实例)和单个车辆(具有不同变速模式的Vehicle
等)。
在我的简化示例中,我想定义一个VehicleType
,然后定义一个Vehicle
,它采用传递给构造函数的VehicleType
的属性。 继伦纳特答案在这里 ,使用__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
。 这也与我对有关__getattr__
的文档的理解相矛盾:
当在常规位置未找到属性时调用该属性(即,它不是实例属性,也不是在自身的类树中找到该属性)。 name是属性名称。
有人可以解释为什么实例van_type
在这里也受到影响吗?
Vehicle
实例没有“容量”属性。
通过自定义__getattr__
,对special_van
上的self.capacities
属性查找(来自Vehicle.add_capacity_dimension
实现)不是在Vehicle
而是在VehicleType
上解析的。
因此, special_van.capacities
和van_type.capacities
是相同的字典。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.