Rechercher le nom et les données d'une variable libre dans un objet fonction

Plus tôt, j'ai écrit sur les fermetures dans Cet article de cas d'utilisation de la définition de fonction imbriquée, mais les noms et les valeurs des variables libres sont pour les objets de fonction. J'ai essayé de savoir comment il est stocké à l'intérieur. (Ci-après, Python 3 est supposé.)

Les variables Python gratuites sont des variables qui sont utilisées dans un bloc de code (pas des variables globales) mais qui ne sont pas définies dans ce bloc et dans [Description](https://docs.python.org/3.6 /reference/executionmodel.html).

Par exemple, dans le code ci-dessous, la variable «y» est utilisée dans une fonction «barre» imbriquée, mais elle est définie à l'intérieur du bloc de définition de la fonction «foo» externe. Ainsi, «y» est une variable locale de la fonction «foo» et une variable libre de la fonction «bar».

python


def foo():
    
    y = "I'm free in bar."

    def bar():
        print(y)
        
    y = "I'm still free in bar."

    return bar

foo renvoie bar, donc pour appeler bar vous avez besoin de deux parenthèses comme ceci:

python


>>> foo()()
I'm still free in bar.

À propos, la valeur de «y» n'est pas l'heure à laquelle «bar» est définie, mais la valeur lorsqu'elle est appelée. Dans l'exemple ci-dessus, «y» est défini deux fois dans «foo», mais vous pouvez voir qu'il s'agit d'une chaîne définie plus tard.

Maintenant, comme pour le sujet principal, du côté de l'objet de la fonction externe foo, le nom de la variable y utilisé à partir de la fonction imbriquée est dans le membre co_cellvars (tuple) de son propre objet de code ( __ code__). Je suis.

python


>>> foo.__code__.co_cellvars
('y',)

D'un autre côté, du côté de l'objet bar, y est nommé comme une variable libre dans le membre co_freevars de l'objet code. (Le toto () ci-dessous est bar.)

python


>>> foo().__code__.co_freevars
('y',)

Le contenu de la variable libre est contenu dans le tuple de l'attribut «closure» en tant qu'objet «cell», et peut être obtenu comme «cell_contents» comme suit.

python


>>> foo().__closure__[0].cell_contents
"I'm still free in bar."

Recommended Posts

Rechercher le nom et les données d'une variable libre dans un objet fonction
Séparation de la conception et des données dans matplotlib
Variables Python et types de données appris avec la chimio-automatique
Récupérer l'appelant d'une fonction en Python
Organiser la signification des méthodes, des classes et des objets
Correction des arguments de la fonction utilisée dans map
L'histoire de la lecture des données HSPICE en Python
Le mémo Python le plus simple au Japon (classes et objets)
Traitement pleine largeur et demi-largeur des données CSV en Python
Extraire et lister les noms des personnes et des lieux dans le texte
Différence entre Ruby et Python en termes de variables
À propos de l'inefficacité du transfert de données dans luigi on-memory
Sélectionnez les variables requises dans TensorFlow et enregistrez / restaurez
Ne pas être conscient du contenu des données en python
Utilisons les données ouvertes de "Mamebus" en Python
Essayez de gratter les données COVID-19 Tokyo avec Python
[Blender] Connaître l'état de sélection des objets cachés sur l'outliner
Découvrez la puissance de l'accélération avec NumPy / SciPy
Avoir le graphique d'équation de la fonction linéaire dessiné en Python
Ordre de référence des variables de classe et des variables d'instance dans "self. Variables de classe" en Python
Recherchez le pandas.DataFrame avec une variable et obtenez la ligne correspondante.
[Homologie] Comptez le nombre de trous dans les données avec Python
Structures de données de type liste et leurs opérations dans le noyau Linux
Rendre la fonction de dessin de polices japonaises dans OpenCV en général
[Astuces] Problèmes et solutions dans le développement de python + kivy
J'ai envoyé les données de Raspberry Pi à GCP (gratuit)
J'ai essayé d'adapter la fonction exponentielle et la fonction logistique au nombre de patients positifs au COVID-19 à Tokyo
À propos des variables et des objets Python
[Python] L'origine du nom de la fonction python
Jugement d'équivalence d'objet en Python
Début de l'analyse de l'encyclopédie Nico Nico ~ Appuyez sur les données fournies par JSON
Racler le calendrier de Hinatazaka 46 et le refléter dans Google Agenda
Essayez de transcrire la fonction de masse stochastique de la distribution binomiale en Python
À propos de Boxplot et Violinplot qui visualisent la variation des données indépendantes
Probabilité des prix les plus élevés et les plus bas des louveteaux à Atsumori
Organiser des blogs utiles dans le domaine de la science des données (outre-mer et Japon)
N'hésitez pas à changer l'étiquette de légende avec Seaborn en python
Notifier le contenu de la tâche avant et après l'exécution de la tâche avec Fabric
Une fonction qui mesure le temps de traitement d'une méthode en python
Creusez le répertoire et créez une liste de chemins de répertoire + noms de fichiers
Créez une fonction pour obtenir le contenu de la base de données dans Go
Vérifier le taux de compression et le temps de PIXZ utilisé en pratique
Obtenez le titre et la date de livraison de Yahoo! News en Python
Configurer un serveur SMTP factice avec Python et vérifier le fonctionnement de l'envoi depuis Action Mailer
Utilisez Cloud Dataflow pour modifier dynamiquement la destination en fonction de la valeur des données et enregistrez-la dans GCS
Lorsque tkinter est démarré dans un autre thread, arrêtez le traitement par ce thread lui-même, nettoyez les variables, puis arrêtez le thread.