将lambda函数设置为属性

时间:2009-11-03 07:35:39

标签: python

考虑这两个类:

class Test(int):
    difference = property(lambda self: self.__sub__)

class Test2(int):
    difference=lambda self: self.__sub__

这两个班级有什么区别吗? :如果是这样,使用属性存储返回另一个函数的lambda函数的目的是什么?

更新:将问题改为我应该首先提出的问题。抱歉。虽然我现在可以从答案中知道解决方案,但在这种情况下我做自我回答是不公平的。 (至少几天没有留下答案)。

更新2 :抱歉,我还不够清楚。问题是关于特定的结构,而不是一般的属性。

6 个答案:

答案 0 :(得分:8)

对于Test1,您可以使用.difference - 对于Test2,您需要使用.difference()代替。

至于为什么要使用它,可能的用途是用动态计算替换以前直接存储为属性的东西。

例如,如果您曾经存储过属性obj.a,那么您扩展了实现,以便它知道可用于计算{{1}的属性obj.bobj.c },但也可用于计算不同的东西。如果您仍然想要使用以前的对象表单提供向后兼容的内容,则可以将a实现为基于obj.a和{{property()计算a的{​​{1}}并且它会像之前那样对那些较旧的代码片段起作用,而不需要进行其他代码修改。

答案 1 :(得分:3)

人们在没有分析它的情况下给出了意见,它可以通过python本身更好地解决,下面是检查差异的代码

import difflib
from pprint import pprint

s1 = """
class Test(int):
    difference=property(lambda self: self.__sub__)
"""

s2 = """
class Test(int):
    difference=lambda self: self.__sub__
"""

d = difflib.Differ()

print "and the difference is..."
for c in d.compare(s1, s2):
    if c[0]  in '+-': print c[1:],

正如预期的那样

and the difference is...
 p  r  o  p  e  r  t  y  (  )

答案 2 :(得分:3)

编辑:啊,我明白了。你在问为什么有人会完全按照上面的代码行事。事实上,这不是一个关于为什么要制作lambda或属性的问题,这不是两个例子之间差异的问题,甚至不是为什么你想用lambda制作一个属性。

你的问题是“为什么有人会让lambda的属性返回self.__sub__”。

答案是:一个人不会。

让我们假设有人想这样做:

>>> foo = MyInt(8)
>>> print foo.difference(7)
1

所以他试图通过这个课来完成它:

class MyInt(int):
    def difference(self, i):
        return self - i

但这是两行,因为他是一名Ruby程序员并且认为好的代码是代码很少的代码,所以他将其更改为:

class MyInt(int):
    difference = int.__sub__

保存一行代码。但显然,事情仍然太容易了。他在Ruby中学到了一个问题没有得到妥善解决,除非你使用匿名代码块,所以他会尝试使用Pythons最近的等价物,lambdas,绝对没有理由:

class MyInt(int):
    difference=lambda self, i: self - i

所有这些都有效。但事情仍然是复杂的,所以相反,他决定通过不进行计算使事情更复杂,但返回子方法:

class MyInt(int):
    difference=lambda self: self.__sub__

啊,但这不起作用,因为他需要调用差异来获得子方法:

>>> foo = MyInt(8)
>>> print foo.difference()(7)
1

所以他把它变成了财产:

class MyInt(int):
    difference=property(lambda self: self.__sub__)

有。现在他找到了解决非问题的最大复杂性。

但正常人不会做这些,但是做:

>>> foo = 8
>>> print foo - 7
1

答案 3 :(得分:2)

是的,在一种情况下,差异是财产。如果您询问属性是什么,可以将其视为自动调用的方法。

答案 4 :(得分:1)

是的,在一种情况下,差异是属性

答案 5 :(得分:1)

财产的目的可以是

1。 在访问属性时提供get / set挂钩
例如如果您曾经拥有属性为a的类,稍后您想在设置时执行其他操作,则可以将该属性转换为属性,而不会影响界面或用户如何使用您的类。因此,在下面的示例中,A类和B类对于用户来说完全相同,但在B内部,您可以在get / setX中执行许多操作

class A(object):
    def __init__(self):
        self.x = 0

a = A()
a.x = 1

class B(object):
    def __init__(self):
        self.x = 0

    def getX(self): return self._x
    def setX(self, x): self._x = x 
    x = property(getX, setX)

b = B()
B.x = 1

2。 如1中暗示的那样,属性是获取/设置调用的更好选择,因此setX用户使用较少详细的self.x和self.x = 1代替getX,尽管我个人从未为获取或设置属性创建属性,如果需要,可以在以后完成,如#1 /

所示

就有关的差异而言,属性为属性提供了get / set / del,但在示例中,您给出了一个方法(lambda或正确的函数)只能用于执行get / set或者del,所以你需要三个这样的lambdas differenceSet,differenceGet,differenceDel