Implementazione di utilizzo di 'con l'oggetto () come f' in classe personalizzata in Python

StackOverflow https://stackoverflow.com/questions/3774328

  •  04-10-2019
  •  | 
  •  

Domanda

Devo aprire un file-come oggetto in python (si tratta di una connessione seriale tramite / dev /) e quindi chiuderlo. Questo viene fatto più volte in diversi metodi di mia classe. Come stavo facendo stava aprendo il file nel costruttore, e chiudendo nel distruttore. Ricevo strani errori e anche se penso che abbia a che fare con il garbage collector e tale, sto ancora non abituato a non sapere esattamente quando i miei oggetti vengono eliminati = \

La ragione per cui stavo facendo questo è perché devo usare tcsetattr con un gruppo di parametri ogni volta che l'apro e diventa fastidioso fare tutto ciò che tutto il luogo. Quindi voglio implementare una classe interna per gestire tutto ciò che così posso usarlo facendo
with Meter('/dev/ttyS2') as m:

che cercavo in linea e non sono riuscito a trovare una buona risposta su come è implementata la sintassi with. Ho visto che utilizza i metodi __enter__(self) e __exit(self)__. Ma è tutto quello che hanno a che fare applicare tali metodi e posso utilizzare la sintassi? O c'è di più ad esso?

C'è sia un esempio di come fare questo o qualche documentazione su come viene implementato su file di oggetti già che posso guardare?

È stato utile?

Soluzione

Tali metodi sono praticamente tutto il necessario per rendere il lavoro oggetto con dichiarazione with.

In __enter__ si deve restituire l'oggetto del file dopo l'apertura e la sua creazione.

In __exit__ si deve chiudere l'oggetto file. Il codice per la scrittura sarà nel corpo dichiarazione 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()

Altri suggerimenti

più semplice potrebbe essere quella di utilizzare libreria standard di Python modulo contextlib :

import contextlib

@contextlib.contextmanager
def themeter(name):
    theobj = Meter(name)
    yield theobj
    theobj.close()  # or whatever you need to do at exit

Questo non fa Meter per sé un gestore di contesto (e quindi non è invasivo per quella classe), ma piuttosto "decora" esso (non nel senso di "sintassi decoratore" di Python, ma quasi, ma non del tutto , nel senso del design pattern decorator ;-) con una funzione di fabbrica themeter che è un gestore di contesto (che il decoratore contextlib.contextmanager costruisce dalla funzione generatore di "single-yield" si scrive) - questo rende così molto più facile da separare l'ingresso e la condizione di uscire, evita nidificazione, ecc.

Il primo Google ha colpito (per me) spiega abbastanza semplicemente:

http://effbot.org/zone/python-with-statement.htm

e il PEP lo spiega più precisamente (ma anche più verboso):

http://www.python.org/dev/peps/pep- 0343 /

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top