2017-05-11 3 views
1

je ma bibliothèque structuré comme tel:Est-ce que la variable globale à l'intérieur d'un sous-module serait rechargée chaque fois que j'appellerais une fonction?

/topmost 
    /__init__.py 
    /submodule 
     /__init__.py 

Avec le submodule.__init__.py, il y a plusieurs fonctions qui utilise des variables globales pour communiquer les uns avec les autres:

import pickle 

def function1(input): 
    global _object1 
    try: 
     _object1 
    except NameError: 
     _object1 = pickle.load(open('model1.pkl', 'rb')) 
    return _object1.func1(input) 

def function2(input): 
    global _object2 
    try: 
     _object2 
    except NameError: 
     _object2 = pickle.load(open('model1.pkl', 'rb')) 
    # Use function1 to do something to the input 
    return _object2.func2(function1(input)) 

Et pour l'utilisateur, ils ne sera pas en mesure d'accéder à la forme _object1 ou _object2 le topmost et dans le topmost.__init__.py, seules les fonctions de submodule ont été importées:

from __future__ import absolute_import 
from topmost.submodule import * 

Et lorsque les utilisateurs utilisent la bibliothèque topmost, ils ne seront exposent à:

>>> import topmost 
>>> topmost.function1('foo bar') 
>>> topmost.function2('foo bar bar') 
>>> topmost.function1('blah blah black sheep') 

Lorsque la première instance de topmost.function1('foo bar') est appelée, l'interprète doit lancer dans la _object1 mondiale dans le cadre topmost.submodule . Mais le _object1 serait-il détruit après que le topmost.function1 ait reçu la valeur retournée?

Plus important encore, lorsque la deuxième instance de topmost.function1('blah blah black sheep') est appelée dans l'extrait d'utilisation ci-dessus, serait le _object1 = pickle.load(open('model1.pkl', 'rb')) être rechargé?

Répondre

1

Les variables globales persistent. Ils ne sont pas détruits par une collecte des ordures. Le module submodule conservera ses variables globales définies jusqu'à ce qu'une telle variable globale de module ne soit pas explicitement définie en utilisant del ou si le module est lui-même déchargé, ce qui normalement ne se produit pas.

Votre utilisation des variables globales de cette manière me semble un peu louche. Ce n'est pas une façon très propre d'écrire du code. Pourquoi ne pas définir les variables en général lors de leur importation? Vous pouvez les définir sur None et vérifier qu'ils ont cette valeur au lieu d'attraper NameError s.

+0

En ce qui concerne la « vérification de variable » et l'utilisation variable globale, je pense aussi qu'il devrait y avoir un meilleur pour résoudre ce problème. J'ai posé une question séparée sur cette question: http://stackoverflow.com/questions/43907083/creating-a-decorator-cache-for-checking-global-variable – alvas

0

Comme Alfe fait allusion à, vous utilisez des vars globaux d'une manière étrange.

Si vous devez utiliser des variables globales, je vous recommande de réécrire le code:

import pickle 
_model1 = None # here we define the global we wish to load the 
       # first time either function is called 

def load_model1(): 
    global _model1 
    if not _model1: 
     _model1 = pickle.load(open('model1.pkl', 'rb')) 
     # No need to write two functions for loading model1 
    return _model1 

def function1(input): 
    return load_model1().func1(input) 

def function2(input): 
    # Use function1 to do something to the input 
    return load_model1().func2(function1(input))