Python 将lambda函数设置为属性

Python 将lambda函数设置为属性,python,Python,以这两类为例: class Test(int): difference = property(lambda self: self.__sub__) class Test2(int): difference=lambda self: self.__sub__ 这两门课有什么不同吗?新增:如果是,使用属性存储返回另一个函数的lambda函数的目的是什么 更新:将问题更改为我首先应该问的问题。很抱歉即使我现在可以从答案中知道答案,但在这种情况下,我做自我回答是不公平的。至少在几天内

以这两类为例:

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

class Test2(int):
    difference=lambda self: self.__sub__
这两门课有什么不同吗?新增:如果是,使用属性存储返回另一个函数的lambda函数的目的是什么

更新:将问题更改为我首先应该问的问题。很抱歉即使我现在可以从答案中知道答案,但在这种情况下,我做自我回答是不公平的。至少在几天内没有留下答案

更新2:对不起,我又不够清楚了。问题是关于特定的构造,而不是一般的属性。

对于Test1,您可以使用.difference-对于Test2,您需要使用.difference

至于为什么要使用它,一个潜在的用途是用动态计算替换以前直接存储为属性的内容


例如,如果您过去存储属性obj.a,但后来扩展了实现,使其知道可以用于计算a,但也可以用于计算不同内容的属性obj.b和obj.c。如果您仍然希望提供与使用以前对象形式的东西的向后兼容性,您可以将obj.a实现为一个基于b和c计算a的属性,并且它将像以前一样对那些旧代码片段进行操作,而不需要其他代码修改。

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

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

人们在没有分析它的情况下给出了他们的意见,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  (  )

编辑:啊,我明白了。你是在问为什么有人会执行上面的代码。事实上,这不是一个为什么要做一个lambda或者一个属性的问题,这不是两个例子之间的区别问题,甚至不是你为什么要用lambda做一个属性的问题

你的问题是,为什么有人会对一个只返回self的lambda做一个属性

答案是:一个人不会

假设有人想这样做:

>>> 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中了解到,除非使用匿名代码块,否则问题无法得到正确解决,因此他会毫无理由地尝试使用python最接近的等价物lambdas:

class MyInt(int):
    difference=lambda self, i: self - i
所有这些工作。但事情仍然很简单,所以他决定让事情变得更复杂,不做计算,而是返回子方法:

class MyInt(int):
    difference=lambda self: self.__sub__
啊,但这不起作用,因为他需要调用difference来获得子方法:

>>> foo = MyInt(8)
>>> print foo.difference()(7)
1
所以他把它变成了一种财产:

class MyInt(int):
    difference=property(lambda self: self.__sub__)
在那里。现在,他已经找到了解决非问题的最大复杂性

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

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

财产的目的可以是

一,。 在访问属性时提供get/set挂钩 e、 g.如果您以前有一个带有属性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
二,。 正如1中所暗示的,属性是get/set调用的更好的替代方法,因此setX用户使用的不是getX,而是更为详细的self.x和self.x=1,尽管就我个人而言,我从来不会仅仅为了获取或设置属性而创建属性,如果需要,可以稍后再创建,如1所示/


就差异而言,属性为您提供了一个atribute的get/set/del,但在示例中,您给出的方法lambda或适当的函数只能用于执行get/set或del中的一个,因此您将需要三个lambda differenceSet、differenceGet、differenceDel

Lolz。顺便说一句,更新后的问题添加了另一个答案,因为这也是一个正确的答案:将答案扩展为匹配。希望现在它100%明确无误。如果原始属性是一个名为.difference的函数,那么您希望该属性的替换实现也返回一个函数。希望,现在已经100%清楚了。谢谢,实际代码在这里:。也许我应该首先提供链接,或者只是用注释询问。我从来不知道lambda函数可以接受多个值。是的,因为该类使用该技术为它在class语句中定义的方法生成别名,这很棘手。我不会使用它,我只会在类定义之后执行OrderedSet.difference=OrderedSet.\uuuuu sub\uuuu。更容易理解。可能更快
,希望您不必通过属性访问,它现在是100%明确的。好的,我更新了我的答案。