2010-11-17 3 views
3

Je sais que "affectation de variable" en python est en fait une liaison/re-bindign d'un nom (la variable) à un objet. Cela soulève la question suivante: est-il possible d'avoir une affectation correcte en python, par exemple rendre un objet égal à un autre objet?Affectation en python

Je suppose qu'il n'y a pas besoin de cela en python:

  1. objets Inmutable ne peuvent pas être « attribués à », car ils ne peuvent pas être modifiés

  2. objets mutables pourraient être affectés à, car ils peuvent changer, et cela pourrait être utile, car vous voudrez peut-être manipuler une copie du dictionnaire séparément de celle d'origine. Cependant, dans ces cas, la philosophie de python est d'offrir une méthode de clonage sur l'objet mutable, de sorte que vous pouvez lier une copie plutôt que l'original.

Je suppose que la réponse est qu'il n'y a pas d'affectation en python, la meilleure façon de mimer ce serait la liaison à un objet cloné

Je voulais simplement partager la question au cas où je suis manque quelque chose d'important ici

Merci

EDIT:

deux Lie Ryan et Sven M répond arnach sont bonnes, je suppose que la réponse globale est un mélange des deux:

Pour les types définis par l'utilisateur, utilisez l'idiome:

a. dict = dict (b. dict)

(Je suppose que cela a des problèmes aussi bien si la classe attribuée a redéfini les méthodes d'accès aux attributs, mais laisse pas difficile :))

Pour mutable Encastrements (listes et dicts) utilisent les méthodes de clonage/copie qu'ils fournissent (par exemple des tranches, mise à jour)

enfin inmutable Encastrements ne peuvent pas être modifiés ne peuvent donc être affectés

Je vais choisir Li Ryan parce que c'est un idiome élégant auquel je n'avais pas pensé.

Merci!

+0

Demandez-vous une copie en profondeur? Est-ce ce que vous voulez dire par "se lier à un objet cloné"? –

Répondre

3

Cela amène la question suivante: est-il possible d'avoir bonne affectation en python, par exemple, faire un objet égal à un autre objet?

Oui, vous pouvez:

a.__dict__ = dict(b.__dict__) 

ferez l'affectation par défaut sémantique dans C/C++ (à savoir faire une affectation peu profonde).

Le problème avec une telle affectation généralisée est qu'elle ne fonctionne jamais pour tout le monde. En C++, vous pouvez remplacer l'opérateur d'affectation car vous devez toujours choisir si vous voulez une affectation totalement superficielle, une affectation entièrement profonde ou toute nuance entre une copie entièrement profonde et une copie totalement superficielle.

1

Je ne pense pas qu'il vous manque quelque chose. J'aime illustrer les variables en python comme le nom écrit sur les 'labels' qui sont attachés aux boîtes mais qui peuvent changer de placement par affectation, alors que dans d'autres langues, l'affectation change le contenu de la boîte (et l'opérateur d'affectation peut être surchargé).

Les débutants peuvent écrire des applications assez complexes sans être conscients de cela, mais ce sont généralement des programmes désordonnés.

4

Je pense que vous avez raison avec votre caractérisation de l'assignation en Python - je voudrais juste ajouter une méthode différente de clonage et des manières d'assignation dans des cas spéciaux.

"Copier-CONSTRUIRE" un mutable objet intégré Python donnera un (peu profond) copie de cet objet:

l = [2, 3] 
m = list(l) 
l is m 
--> False 

[Modifier: Comme l'a souligné Paul McGuire dans les commentaires , le comportement d'un "constructeur de copie" (pardonnez-moi la terminologie C++) pour un immuable objet Python intégré est dépendant de l'implémentation - vous pourriez obtenir une copie ou juste le même objet. Mais parce que l'objet est immuable de toute façon, vous ne devriez pas s'en soucier.]

Le constructeur de copie pourrait être appelé génériquement par y = type(x)(x), mais cela semble un peu énigmatique. Et bien sûr, il y a le module copy qui permet des copies superficielles et profondes.

Certains objets Python permettent l'affectation. Par exemple, vous pouvez attribuer à une liste sans créer un nouvel objet:

l = [2, 3] 
m = l 
l[:] = [3, 4, 5] 
m 
--> [3, 4, 5] 

Pour les dictionnaires, vous pouvez utiliser la méthode suivie par clear()update(otherdict) assigner à un dictionnaire sans créer un nouvel objet. Pour un ensemble s, vous pouvez utiliser

s.clear() 
s |= otherset 
+0

Vos hypothèses de "constructeur de copie" * peuvent être vraies pour les classes Python intégrées, mais elles ne sont généralement pas garanties pour toutes les classes et tous les objets. Je peux très facilement créer une classe immuable qui prend une instance de lui-même pour la construction, mais fait un objet entièrement différent avec les mêmes valeurs, telles que 'copy == original' est True, mais' copy is original' est False. – PaulMcG

+0

Je viens de remarquer que vous avez déjà qualifié votre réponse pour la restreindre aux classes intégrées. – PaulMcG

+0

Une brève expérience avec Jython 2.5.0 montre que ceci n'est pas vrai pour les chaînes. : >>> a = "SLJDFSDLJ" >>> b = str (a) >>> b est un False - ce que vous avez décrit est une optimisation d'implémentation spécifique à CPython, mais non garantie par la spécification du langage Python. – PaulMcG