Puis-je écrire une fonction qui détecte si elle est appelée de « with'-déclaration ou non?

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

  •  11-10-2019
  •  | 
  •  

Question

Plus précisément, je peux détecter si une fonction est appelée EXPR dans la déclaration de with EXPR: BLOCK? Je suis en train de me familiariser avec l'utilisation de with-déclaration en python. Dans un premier temps, je réimplémenté un exemple, qui a marqué en texte générer, paru dans la référence de contextlib.contextmanager (en ignorant la gestion des exceptions pour l'instant).

class Markup(object):
    def __init__(self):
        self.tags = []
        self.append = self.tags.append
        self.pop = self.tags.pop

    def tag(self, name):
        self.append(name)
        return self

    def __enter__(self):
        print('<{}>'.format(self.tags[-1]))

    def __exit__(self, exc_type, exc_value, traceback):
        print('</{}>'.format(self.pop()))

>>> m = Markup()
>>> with m.tag('ELEMENT'):
...     print('sample text')
...
<ELEMENT>
sample text
</ELEMENT>

Cela fonctionne comme prévu. Ensuite, je suis arrivé à penser si tag() peut également générer des éléments vides:

>>> m = Markup()

# if a function appears as EXPR of "with EXPR: BLOCK", 'ELEMENT' is a container element. .
>>> with m.tag('ELEMENT'):
...     print('sample text')
...
<ELEMENT>
sample text
</ELEMENT> 

# in other cases, ELEMENT is an empty element.
>>> m.tag('ELEMENT')
<ELEMENT/>

A mes yeux naïfs, il semble faisable si peut détecter si callee est appelée à partir de la déclaration with ou non. Cependant, je ne sais pas si cette détection est possible ou non. Y at-il une telle façon et, si oui, comment?

Était-ce utile?

La solution

Vous n'êtes pas appeler réellement tag() « de » la déclaration de with. Vous appelez tag(), en faisant passer la valeur de retour de tag() à la déclaration de with, qui appelle ensuite __enter__ sur ce passé en valeur, puis exécute le corps, puis appelle __exit__.

Donc non, vous ne pouvez pas détecter l'instruction with avant qu'il ne soit effectivement invoqué (qui est après tag() est appelé).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top