12
votes

Retourner un lvalue d'une fonction en python

[Désolé, je suis nouveau à Python. Bien que cela semble être une question très fondamentale, j'ai fait ma part de diligence raisonnable avant de demander à ce public, essayant d'éviter des questions vraiment stupides].

J'essaie de comprendre l'idiome correct pour le retour d'une valeur L de une fonction. Supposons que j'ai un conteneur de 64 objets et je souhaite pouvoir renvoyer une référence à ces objets. P>

board = ChessBoard()
board.square(0,0) = Piece( Shapes.ROOK, Colors.White )    <-- I'm getting an error here
board.square(0,1) = Piece( Shapes.BISHOP, Colors.White )
... etc.


0 commentaires

4 Réponses :


10
votes

en python, tout est une référence. Le seul problème est que Aucun est immuable , vous ne pouvez donc pas utiliser la référence renvoyée pour modifier la valeur.

Vous ne pouvez pas non plus remplacer l'opérateur d'affectation, Donc, vous ne recevrez pas ce genre de comportement particulier. Cependant, une bonne et très flexible solution serait de remplacer le __ Settitem __ et __ getItem __ Méthodes pour implémenter l'opérateur d'abonnement ( [] ) pour la classe: xxx

utilisation: xxx


2 commentaires

Notez que la définition est légèrement plus laide dans 3.x, car le cas particulier du déballage du tuple dans les listes d'argumentation s'est allé la voie du bleu norvégien. Vous devriez définir def __setem __ (Self, Row_Col, Valeur): Rangée, Col = Row_Col; Self.Squares [rangée * 8 + col] = valeur .


@Delnan: Merci, je l'ai changé parce que le reste est la version-agnostique. Je pense que le choix de supprimer cette fonctionnalité est malheureux, il peut être vraiment utile s'il est utilisé sensiblement.



1
votes

Comme le souligne Niklas, vous ne pouvez pas retourner une valeur L.

Toutefois, en plus de souscription de remplacement, vous pouvez également utiliser Propriétés ( Une application de descripteurs: http://docs.python.org/howto/descriptor.htmlleight/a >) Pour créer un attribut d'objet, lequel lorsque vous lisez ou attribué à, exécute le code.



1
votes

(Ne répondant pas à votre question dans le titre, mais votre «Comment approcheriez-vous cette structure de données?» Question :) Une solution plus pythonique pour votre structure de données utiliserait une liste de listes:

# define a function that generates an empty chess board
make_chess_board = lambda : [[None for x in xrange(8)] for y in xrange(8)]

# grab an instance
b = make_chess_board()

# play the game!
b[0][0] = Piece(Shapes.ROOK, Colors.White)
b[0][1] = Piece(Shapes.BISHOP, Colors.White)

# Or use tuples:
b[0][0] = (Shapes.ROOK, Colors.White)
b[0][1] = (Shapes.BISHOP, Colors.White)


0 commentaires

2
votes

Vous pouvez essayer quelque chose comme ceci, au prix d'avoir à mettre de bogus [:] indexeurs autour de: xxx

alors vous pouvez faire xxx

et ainsi de suite. Cela ne comporte pas ce que vous mettez dans la [] s, il doit simplement être quelque chose.

(obtenu l'idée des proxies Perl6 utilise pour le faire)


1 commentaires

Pouvez-vous s'il vous plaît poster la source d'où vous avez eu cette idée?