开发者

Setting a lambda function as a property

Consider these two classes:

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

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

Is there any difference between these two classes? New: If so, what is the purpose of using the property to store a lambda function that returns another function?

Update: Changed the q开发者_运维百科uestion to what I should have asked in the first place. Sorry. Even though I can now know the solution from the answers, it would be unfair for me to do a self answer in these circumstances. (without leaving the answer for a few days at least).

Update 2: Sorry, I wasn't clear enough again. The question was about the particular construction, not properties in general.


For Test1, you could use .difference - for Test2, you'd need to use .difference() instead.

As for why you might use it, a potential use would be to replace something that was previously directly stored as a property with a dynamic calculation instead.

For instance, if you used to store property obj.a, but then you expanded your implementation so that it knew instead properties obj.b and obj.c that could be used to calculate a, but could also be used to calculate different things. If you still wanted to provide backwards-compat with things that used the previous object form, you could implement obj.a as a property() that calculated a based on b and c and it'd behave to those older code fragments as it previously did, with no other code modification needed.


Edit: Ah, I see. You are asking why anybody would do exactly the code above. It's not, in fact a question about why to make a lambda or a property at all, it's not a question of the differences between the two examples, and not even why you want to make a property out of a lambda.

Your question is "Why would anybody make a property of a lambda that just returns self.__sub__".

And the answer is: One wouldn't.

Let's assume somebody wants to do this:

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

So he tries to accomplish it by this class:

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

But that's two lines, and since he is a Ruby programmer and believes that good code is code that has few lines of code, he changes it to:

class MyInt(int):
    difference = int.__sub__

To save one line of code. But apparently, things are still too easy. He learned in Ruby that a problem is not properly solved unless you use anonymous code blocks, so he will try to use Pythons nearest equivalent, lambdas, for absolutely no reason:

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

All these works. But things are still WAY to uncomplicated, so instead he decides to make things more complex, by not doing the calculation, but returning the sub method:

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

Ah, but that doesn't work, because he needs to call difference to get the sub-method:

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

So he makes it a property:

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

There. Now he has found the maximum complexity to solve a non-problem.

But normal people wouldn't do any of these, but do:

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


People have given there opinion without analyzing it, it can be better solved by python itself, below is the code to check the difference

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 as expected it says

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


Yes, in one case difference is a property. If you are asking what a property is, you can see it as a method that gets automatically called.


Yes, in one case difference is a property


Purpose of property can be

1. To provide get/set hooks while accessing an attribute
e.g. if you used to have class with attribute a, later on you want to do something else when it is set, you can convert that attribute to property without affecting the interface or how users use your class. So in the example below class A and B are exactly same for a user but internally in B you can do many things in 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. As implied in 1, property is a better alternative to get/set calls, so instead of getX, setX user uses less verbose self.x and self.x = 1, though personally I never make a property just for getting or setting a attribute, if need arises it can be done later on as shown in #1/

as far as difference in concerned, property provide you with get/set/del for an atribute, but in the example you have given a method(lambda or proper function) can only be used to do one of get/set or del, so you will need three such lambdas differenceSet, differenceGet, differenceDel

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜