2009-11-03 6 views
0

Tenir compte de ces deux classes:Définition d'une fonction lambda comme une propriété

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

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

est-il une différence entre ces deux classes? Nouveau: Si oui, quel est le but de l'utilisation de la propriété pour stocker une fonction lambda qui renvoie une autre fonction?

Mise à jour: Changement de la question à ce que j'aurais dû demander en premier lieu. Pardon. Même si je peux maintenant connaître la solution à partir des réponses, il serait injuste de ma part de faire une auto-réponse dans ces circonstances. (sans laisser la réponse pour quelques jours au moins).

Mise à jour 2: Désolé, je n'étais pas encore assez clair. La question portait sur la construction particulière, pas sur les propriétés en général.

+0

OK, j'ai mis à jour ma réponse. –

Répondre

3

Édition: Ah, je vois. Vous demandez pourquoi quelqu'un ferait exactement le code ci-dessus. En fait, ce n'est pas une question de savoir pourquoi faire un lambda ou une propriété, ce n'est pas une question de différences entre les deux exemples, et même pas pourquoi vous voulez faire une propriété sur un lambda.

Votre question est "Pourquoi quelqu'un ferait-il une propriété d'un lambda qui retourne simplement self.__sub__".

Et la réponse est: On ne le ferait pas.

Supposons que quelqu'un veut faire:

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

Alors, il tente de l'accomplir par cette classe:

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

Mais c'est deux lignes, et comme il est un programmeur Ruby et croit ce bon code est le code qui a quelques lignes de code, il le change en:

class MyInt(int): 
    difference = int.__sub__ 

Pour économiser un l ine de code. Mais apparemment, les choses sont encore trop faciles. Il a appris à Ruby qu'un problème est résolu pas correctement à moins que vous utilisez des blocs de code anonymes, donc il va essayer d'utiliser Pythons équivalent le plus proche, lambdas, sans aucune raison:

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

Toutes ces œuvres. Mais les choses sont encore du chemin à simple, donc au lieu qu'il décide de rendre les choses plus complexes, en ne faisant pas le calcul, mais le retour de la méthode sous:

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

Ah, mais cela ne fonctionne pas, parce qu'il a besoin de appeler la différence pour obtenir la sous-méthode:

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

il a donc fait une propriété:

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

il. Maintenant, il a trouvé la complexité maximale pour résoudre un non-problème.

Mais les gens normaux ne faire aucune de ces derniers, mais ne:

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

Espérons, il est 100% sans ambiguïté maintenant. – Casebash

+0

Merci, le code réel était ici: http://stackoverflow.com/questions/1653970/does-python-have-an-ordered-set/1653978#1653978. Peut-être que j'aurais dû fournir le lien en premier lieu ou juste demander un commentaire – Casebash

+0

Je n'ai jamais su que les fonctions lambda pouvaient prendre plusieurs valeurs – Casebash

8

Pour Test1, vous pouvez utiliser .difference - pour Test2, vous devez utiliser .difference() à la place. Pour ce qui est de savoir pourquoi vous pourriez l'utiliser, il pourrait être utile de remplacer à la place quelque chose qui était auparavant directement stocké en tant que propriété avec un calcul dynamique.

Par exemple, si vous avez utilisé pour stocker des biens obj.a, mais vous avez décompressé votre mise en œuvre afin qu'il savait au lieu des propriétés obj.b et obj.c qui pourraient être utilisés pour calculer a, mais pourrait également être utilisé pour calculer des choses différentes. Si vous vouliez toujours fournir un récapitulatif avec des objets qui utilisaient la forme d'objet précédente, vous pouviez implémenter obj.a comme un property() qui calculait a sur la base de b et c et il se comporterait comme précédemment avec ces anciens fragments de code, sans aucun autre modification de code nécessaire.

+0

Mis à jour la question – Casebash

+0

Élargi la réponse pour correspondre. – Amber

+0

Heureusement, il est 100% sans ambiguïté maintenant. – Casebash

2

Oui, dans un cas, la différence est une propriété. Si vous demandez ce qu'est une propriété, vous pouvez la voir comme une méthode appelée automatiquement.

+0

Mis à jour le – Casebash

1

Oui, dans une différence de cas est une propriété

+0

Mise à jour de la question – Casebash

3

Les gens ont donné là opinion sans l'analyser, il peut être mieux résolu en python lui-même, ci-dessous est le code pour vérifier la différence

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:], 

et comme prévu il est dit

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

Lolz. BTW, Mise à jour la question – Casebash

+0

ajouté une autre réponse, parce que celui-ci est aussi une réponse correcte :) –

1

Objet de la propriété peut être

1. Fournir des crochets get/set tout en accédant à un attribut
par exemple Si vous aviez auparavant la classe avec l'attribut a, plus tard vous voulez faire autre chose quand il est défini, vous pouvez convertir cet attribut en propriété sans affecter l'interface ou la façon dont les utilisateurs utilisent votre classe. Ainsi, dans l'exemple ci-dessous classe A et B sont exactement les mêmes pour un utilisateur, mais en interne B vous pouvez faire beaucoup de choses 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. Comme implicite dans 1, la propriété est une meilleure alternative pour obtenir/set, donc à la place de getX, l'utilisateur setX utilise moins self.x et self.x = 1, même si personnellement je ne fais jamais une propriété juste pour obtenir ou définir un attribut, si besoin est, cela peut être fait plus tard comme montré Dans la mesure où la différence est concernée, la propriété vous fournit get/set/del pour un attribut, mais dans l'exemple vous avez donné une méthode (lambda ou fonction propre) ne peut être utilisée que pour faire un de get/set ou del, donc vous aurez besoin de trois tels lambdas differenceSet, differenceGet, differenceDel

+0

Heureusement, il est 100% sans ambiguïté maintenant. – Casebash

Questions connexes