Bonjour, après avoir étudié cette question pendant un moment, je suis arrivé à la conclusion :
C'est trop difficile à faire et la syntaxe que vous souhaitez utiliser ne correspond pas à ce que vous essayez de faire
Je pense qu'il n'y a rien de mal à utiliser la méthode originale
Si vous souhaitez réaliser l'échange que vous avez défini, alors j'ai une alternative qui n'est pas trop belle, vous pouvez vous référer à
Ce qui suit est une explication des trois points ci-dessus :
Pour le premier point, vous souhaitez :
db1, db2 = db2, db1
Peu importe le type d'objet db1, db2, le sens de cet échange est
Laissez la variable db1 faire référence à l'objet initialement référencé par db2, et laissez la variable db2 faire référence à l'objet initialement référencé par db1.
Mais ce que vous voulez faire, c'est :
Que le contenu du db1 fichier et du db2 fichier soit échangé
Réfléchissez bien, ces deux choses ne sont pas identiques. Pour le dire autrement, db1, db2 = db2, db1 fera uniquement échanger les éléments référencés par les variables (le nom de la variable n'est pas égal au nom du fichier de la base de données) , mais le nom de chaque fichier Le contenu n'est toujours pas échangé.
Donc utiliser cette syntaxe pour échanger n'est pas cohérent avec l'effet que vous souhaitez obtenir.
Je ne m’étendrai pas sur le deuxième point car c’est raisonnable, mais cela ne vous plaira peut-être pas.
Le troisième point est que j'ai donné une alternative moins belle, qui consiste simplement à définir une classe proxy shelf de ShelfProxy. Cette classe tente de simuler le comportement de la classe Shelf (seule l'interface est similaire. ), et l'opérateur surchargé ^ est défini comme échange :
import shelve
class ShelfProxy:
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
self.file = args[0]
self.loaddb()
@classmethod
def open(cls, *args, **kwargs):
return cls(*args, **kwargs)
def __getattr__(self, name):
return getattr(self.dic, name)
def __setitem__(self, name, value):
self.dic[name] = value
def __getitem__(self, name):
return self.dic[name]
def __xor__(self, other):
self.dic, other.dic = other.dic, self.dic
return True
def __str__(self):
return str(self.dic)
def loaddb(self):
db = shelve.open(*self.args, **self.kwargs)
self.dic = dict(db.items())
db.close()
def close(self):
newdb = shelve.open(self.file, *self.args[1:], **self.kwargs)
for key in newdb.keys():
del newdb[key]
for key, value in self.dic.items():
newdb[key] = value
newdb.close()
Je définis ^ comme l'échange de contenu dans . La raison pour laquelle j'ai choisi ^ est simplement parce que je ne peux pas penser à un symbole plus approprié. De manière générale, la surcharge ne sera pas. fait de cette façon, et ce n'est pas très facile. Les instances d'autres classes seront renvoyées, mais j'ai fait cela pour plus de commodité et parce que vous voulez une interface simple.
Ensuite nous définissons quelques fonctions de test :
La plupart du temps, vous pouvez utiliser la même interface que Shelf pour faire fonctionner ShelfProxy, et l'effet global est similaire, mais ne pensez-vous pas qu'il est plus facile d'utiliser la méthode depuis le début après avoir autant écrit ?XD
Bonjour, après avoir étudié cette question pendant un moment, je suis arrivé à la conclusion :
C'est trop difficile à faire et la syntaxe que vous souhaitez utiliser ne correspond pas à ce que vous essayez de faire
Je pense qu'il n'y a rien de mal à utiliser la méthode originale
Si vous souhaitez réaliser l'échange que vous avez défini, alors j'ai une alternative qui n'est pas trop belle, vous pouvez vous référer à
Ce qui suit est une explication des trois points ci-dessus :
Pour le premier point, vous souhaitez :
Peu importe le type d'objet
db1
,db2
, le sens de cet échange estMais ce que vous voulez faire, c'est :
Réfléchissez bien, ces deux choses ne sont pas identiques. Pour le dire autrement,
db1, db2 = db2, db1
fera uniquement échanger les éléments référencés par les variables (le nom de la variable n'est pas égal au nom du fichier de la base de données) , mais le nom de chaque fichier Le contenu n'est toujours pas échangé.Donc utiliser cette syntaxe pour échanger n'est pas cohérent avec l'effet que vous souhaitez obtenir.
Je ne m’étendrai pas sur le deuxième point car c’est raisonnable, mais cela ne vous plaira peut-être pas.
Le troisième point est que j'ai donné une alternative moins belle, qui consiste simplement à définir une classe proxy
shelf
deShelfProxy
. Cette classe tente de simuler le comportement de la classeShelf
(seule l'interface est similaire. ), et l'opérateur surchargé^
est défini comme échange :Je définis
^
comme l'échange de contenu dans . La raison pour laquelle j'ai choisi^
est simplement parce que je ne peux pas penser à un symbole plus approprié. De manière générale, la surcharge ne sera pas. fait de cette façon, et ce n'est pas très facile. Les instances d'autres classes seront renvoyées, mais j'ai fait cela pour plus de commodité et parce que vous voulez une interface simple.Ensuite nous définissons quelques fonctions de test :
Code de test :
Résultat :
Conclusion
La plupart du temps, vous pouvez utiliser la même interface que
Shelf
pour faire fonctionnerShelfProxy
, et l'effet global est similaire, mais ne pensez-vous pas qu'il est plus facile d'utiliser la méthode depuis le début après avoir autant écrit ?XDQuestions auxquelles j'ai répondu : Python-QA