La mise en oeuvre de l'utilisation « avec l'objet () as f » dans la classe de produits en python
-
04-10-2019 - |
Question
Je dois ouvrir un fichier comme objet en python (il est une connexion série à / dev /), puis fermez-le. Cela se fait à plusieurs reprises dans plusieurs méthodes de ma classe. Comment je le faisais était d'ouvrir le fichier dans le constructeur, puis le fermer dans le destructor. Je reçois des erreurs étranges et si je pense qu'il a à voir avec le collecteur des ordures et comme, je ne suis toujours pas habitué à ne pas savoir exactement quand mes objets sont supprimés = \
La raison pour laquelle je faisais cela est parce que je dois utiliser tcsetattr
avec un tas de paramètres à chaque fois que je l'ouvre et il devient gênant de faire tout ce que partout. Je veux donc mettre en œuvre une classe interne pour gérer tout ce que je puisse l'utiliser à faire
with Meter('/dev/ttyS2') as m:
Je cherchais en ligne et je ne pouvais pas trouver une très bonne réponse sur la façon dont la syntaxe with
est mis en œuvre. J'ai vu qu'il utilise les méthodes de __enter__(self)
et __exit(self)__
. Mais est tout ce que je dois faire appliquer ces méthodes et je peux utiliser la syntaxe avec? Ou est-il de plus?
est-il soit un exemple sur la façon de le faire ou de certains documents sur la façon dont il est mis en œuvre sur les objets fichier déjà que je peux regarder?
La solution
Ces méthodes sont à peu près tout ce que vous avez besoin pour faire le travail d'objet à l'énoncé de with
.
Dans __enter__
vous devez renvoyer l'objet fichier après l'avoir ouvert et sa mise en place.
Dans __exit__
vous devez fermer l'objet de fichier. Le code pour l'écriture, il sera dans le corps de l'instruction with
.
class Meter():
def __init__(self, dev):
self.dev = dev
def __enter__(self):
#ttysetattr etc goes here before opening and returning the file object
self.fd = open(self.dev, MODE)
return self.fd
def __exit__(self, type, value, traceback):
#Exception handling here
close(self.fd)
meter = Meter('dev/tty0')
with meter as m:
#here you work with the file object.
m.read()
Autres conseils
peut être à Easiest utiliser le module bibliothèque standard Python contextlib :
import contextlib
@contextlib.contextmanager
def themeter(name):
theobj = Meter(name)
yield theobj
theobj.close() # or whatever you need to do at exit
Cela ne fait pas Meter
lui-même un gestionnaire de contexte (et est donc non-invasive à cette classe), mais plutôt « décore » il (pas dans le sens de la « syntaxe de décorateur » de Python, mais presque, mais pas tout à fait , dans le sens du modèle de conception de décorateur ;-) avec une fonction d'usine themeter
qui un gestionnaire de contexte (que le décorateur contextlib.contextmanager
construit à partir de la fonction de générateur « single-yield
» vous écrivez) - ce en fait si beaucoup plus facile de séparer l'entrée et la sortie de l'état, évite la nidification, etc..
Le premier Google a frappé (pour moi) explique assez simplement:
http://effbot.org/zone/python-with-statement.htm
et le PEP explique plus précisément (mais aussi plus verbeux):