Utiliser Python, existe-t-il un moyen de stocker une référence à une référence, de sorte que je puisse changer ce que cette référence fait référence dans un autre contexte? Par exemple, supposons que j'ai la classe suivante:
f = Foo() rStandalone = Reassigner(f.standalone) # presumably this syntax might change rIndex = Reassigner(f.lst[1]) rStandalone.reassign(7) rIndex.reassign(9)
4 Réponses :
En bref, ce n'est pas possible. Du tout. L'équivalent le plus proche consiste à enregistrer une référence à l'objet dont le membre / élément que vous souhaitez réaffecter, plus le nom d'attribut / index / clé, puis utilisez setattr code> /
SETITEM code>. Cependant, cela donne une syntaxe assez différente, et vous devez différencier entre les deux:
class AttributeReassigner:
def __init__(self, obj, attr):
# use your imagination
def reassign(self, val):
setattr(self.obj, self.attr, val)
class ItemReassigner:
def __init__(self, obj, key):
# use your imagination
def reassign(self, val):
self.obj[self.key] = val
f = Foo()
rStandalone = AttributeReassigner(f, 'standalone')
rIndex = ItemReassigner(f.lst, 1)
rStandalone.reassign(7)
rIndex.reassign(9)
réponse simple: vous ne pouvez pas.
Pourquoi __ settitem __ code> et pas seulement l'accès direct de l'article avec
[] code>?
Duh, parce que ça ne serait pas une lambda
Comme Eric semble avoir réalisé :), f.lst [1] = la valeur code> n'est pas une expression, mais
f.lst .__ Settitem __ (1, valeur) code> est.
Cela fonctionnerait pour le contenu des objets de conteneur. Si cela ne vous dérange pas d'ajouter un niveau d'indirection à vos variables (que vous auriez besoin dans le boîtier du pointeur à pointer-to-Pointer), vous pouvez:
Class Reassigner(object): def __init__(self, target): self.target = target def reassign(self, value): self.target.val = value
Si vous devez différer des tâches; Vous pouvez utiliser si functools.partial code> (ou juste
lambda code>):
réaffectation code> est la seule opération ; Vous n'avez pas besoin d'une nouvelle classe.
Les fonctions sont des citoyens de première classe à Python: vous pouvez les affecter à une variable, stocker dans une liste, passer comme arguments, etc. p> p>
Opérateur.Setitem Code> rend le cas de l'élément symétrique à l'affaire Attribut, et semble mieux.
@Delnan: J'y ai pensé, mais je voulais démontrer que partiel code> fonctionne également sur des méthodes (non seulement des fonctions) et il existe également des méthodes spéciales en Python. Sinon
opérateur.Setitem code> peut être préférable car il reporte le fichier
__ settitem __ code> recherche (exceptions sont sur le site de l'appelant).
Je pense que l'ensemble des références est que vous ne devriez pas être capable de le faire.
Comment avez-vous l'intention d'utiliser cela?
Si vous voulez C ++, vous savez où le trouver ...
@FogleBird Le plan était dans une affectation différée de références nommées. Un tas d'objets est chargé à partir de fichiers XML, ce qui peut faire référence à d'autres objets par nom. Si vous faites référence à un nom qui n'existe pas encore, vous obtenez un objet d'espace réservé et soyez coincé dans une table de choses avec des références dangereuses. Si vous rencontrez plus tard la définition de ce nom, vous suivriez toutes les entrées appropriées du tableau des références en suspens et réaffectait les valeurs d'espace réservé aux objets nouvellement créés. Il existe des solutions avec des couches d'indirection, mais j'espérais quelque chose de direct.
@professional_yet_not_trackable qui est exactement b> (modulo xml) Ce que je faisais quand j'ai rencontré ce problème et j'ai trouvé la solution qui est maintenant ma réponse. Soutient ma théorie selon laquelle il existe extrêmement peu d'utilisations pour cela.
Je fais habituellement une charge à deux passes pour ce scénario. Tout d'abord, chargez tous les objets (et utilisez un dict pour mapper ID => Objet), puis effectuez une autre passe pour établir les liens entre les objets.