如何工作python属性工厂和嵌套函数

时间:2017-10-24 01:28:26

标签: python

在“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

2 个答案:

答案 0 :(得分:1)

函数quantity构建并返回由语句return property(qty_getter, qty_setter)定义的属性实例。

该属性本身包含两个嵌套函数qty_getterqty_setter。封闭函数可以访问父函数参数(以类似于闭包的方式)。

当你调用self.weight(在小计函数中)时,你告诉python调用分配给qty_getter的属性的getter函数(self.weight)。

对于getter(或setter)函数,通过属性契约,提供了保存属性本身的对象的实例(在本例中为LineItem),而该对象又可以访问storage_name变量。

答案 1 :(得分:0)

Python中的property是一个特殊的装饰器。装饰器只是放置包装其他对象的函数,通常是类字段。

难以理解的一点是上面的quantity不是一个类,而是一个函数。在该函数内部有两个嵌套函数:qty_getterqty_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中的字段,在内部使用辅助方法查找该字段。该属性将覆盖此处的默认行为,而是调用属性中定义的函数。您在那里看到的instanceLineItem的实例。它与普通方法中的self相当,除非您在此处访问其他对象self