在“fluent python”的“编码属性工厂”一节中,代码如下:
def quantity(storage_name):def qty_getter(instance): # B return instance.__dict__[storage_name] def qty_setter(instance, value): if value > 0: instance.__dict__[storage_name] = value else: raise ValueError('value must be > 0') return property(qty_getter, qty_setter)
class LineItem: weight = quantity('weight') # A price = quantity('price')
def __init__(self, description, weight, price): self.description = description self.weight = weight self.price = price def subtotal(self): return self.weight * self.price
在“A”中只传递一个参数,但在函数中接收两个参数:storage_name和instance。我很困惑,“B”中的参数“实例”如何传递给qty_getter
答案 0 :(得分:1)
函数quantity
构建并返回由语句return property(qty_getter, qty_setter)
定义的属性实例。
该属性本身包含两个嵌套函数qty_getter
和qty_setter
。封闭函数可以访问父函数参数(以类似于闭包的方式)。
当你调用self.weight
(在小计函数中)时,你告诉python调用分配给qty_getter
的属性的getter函数(self.weight
)。
对于getter(或setter)函数,通过属性契约,提供了保存属性本身的对象的实例(在本例中为LineItem),而该对象又可以访问storage_name
变量。
答案 1 :(得分:0)
Python中的property
是一个特殊的装饰器。装饰器只是放置包装其他对象的函数,通常是类字段。
难以理解的一点是上面的quantity
不是一个类,而是一个函数。在该函数内部有两个嵌套函数:qty_getter
和qty_setter
。请注意,在您的班级中,您只是直接使用外部函数。 quantity
函数返回
property(qty_getter, qty_setter)
property
这是一个内置的Python,以一种特殊的方式运行。每当您尝试设置属性的值时,都会使用新值调用qty_setter
。如果要获取当前值,则会调用qty_getter
。
由于属性绑定到一个类,你通常会在该类上调用它。实例,例如:
line = LineItem()
line.weight = 10 # weight setter called here
print(line.price) # price getter called here
line.subtotal # this method accesses both getters
每当你访问一个班级' Python中的字段,在内部使用辅助方法查找该字段。该属性将覆盖此处的默认行为,而是调用属性中定义的函数。您在那里看到的instance
是LineItem
的实例。它与普通方法中的self
相当,除非您在此处访问其他对象self
。