web-dev-qa-db-fra.com

Accéder à une variable de fonction en dehors de la fonction sans utiliser "global"

J'essaie d'accéder à une variable de fonction locale en dehors de la fonction en Python. Donc, par exemple,

bye = ''
def hi():
    global bye
    something
    something
    bye = 5
    sigh = 10

hi()
print bye

Ce qui précède fonctionne bien comme il se doit. Puisque je veux savoir si je peux accéder à bye en dehors de hi() sans utiliser global bye, j'ai essayé:

def hi():
    something
    something
    bye = 5 
    sigh = 10
    return

hi()
x = hi()
print x.bye 

Ce qui précède donne AttributeError: 'NoneType' object has no attribute 'bye'.

Ensuite, j'ai essayé:

def hi():
    something
    something
    bye = 5
    sigh = 10
    return bye 
hi()
x = hi()
print x.bye

Cette fois, cela ne donne même pas une erreur.

Donc, y a-t-il un moyen d'accéder à une variable de fonction locale (bye) en dehors de sa fonction (hi()) sans utiliser de globals et sans afficher la variable sigh (La question a été modifiée pour inclure sigh après le commentaire de @hcwhsa ci-dessous.

25
user2480526

Vous pouvez faire quelque chose dans ce sens (qui fonctionnait à la fois dans Python v2.7.15 et v3.7.1 lorsque je l’ai/testé):

def hi():
    # other code...
    hi.bye = 42  # Create function attribute.
    sigh = 10

hi()
print(hi.bye)  # -> 42

Les fonctions sont des objets en Python et peuvent recevoir des attributs arbitraires.

Si vous faites souvent ce genre de choses, vous pouvez implémenter quelque chose de plus générique en créant un décorateur de fonctions qui ajoute un argument this à chaque appel de la fonction décorée. 

Cet argument supplémentaire donnera aux fonctions un moyen de se référencer elles-mêmes sans avoir à l'intégrer explicitement (code dur) dans leur définition. Il est similaire à l'argument d'instance que les méthodes de classe reçoivent automatiquement comme premier argument, généralement nommé self. évitez la confusion, mais comme l’argument self, vous pouvez le nommer comme vous le souhaitez.

Voici un exemple de cette approche:

def with_this_arg(func):
    def wrapped(*args, **kwargs):
        return func(wrapped, *args, **kwargs)
    return wrapped

@with_this_arg
def hi(this, that):
    # other code...
    this.bye = 2 * that  # Create function attribute.
    sigh = 10

hi(21)
print(hi.bye)  # -> 42
60
martineau

Le problème est que vous appelez print x.bye après avoir défini x en tant que chaîne. Lorsque vous exécutez x = hi(), il exécute hi () et définit la valeur de x sur 5 (la valeur de bye; il ne définit PAS la valeur de x en tant que référence à la variable bye elle-même). EX: bye = 5; x = bye; bye = 4; print x; imprime 5 et non 4

De plus, vous n'avez pas besoin de lancer hi () deux fois, mais simplement x = hi(), et non hi();x=hi() (comme vous l'aviez dit: hi (), ne faites rien avec la valeur résultante de 5, puis relancez le même ) et enregistrer la valeur de 5 dans la variable x.

Donc, le code complet devrait être

def hi():
    something
    something
    bye = 5
    return bye 
x = hi()
print x

Si vous souhaitez renvoyer plusieurs variables, une option consiste à utiliser une liste ou un dictionnaire, selon vos besoins.

ex:

def hi():
    something
    xyz = { 'bye': 7, 'foobar': 8}
    return xyz
x = hi()
print x['bye']

plus sur les dictionnaires python sur http://docs.python.org/2/tutorial/datastructures.html#dictionaries

7
John
 def hi():
     bye = 5
     return bye  

print hi()
1
Allan Mwesigwa

Vous pouvez faire quelque chose dans ce sens:

def static_example():
   if not hasattr(static_example, "static_var"):
       static_example.static_var = 0
   static_example.static_var += 1
   return static_example.static_var

print static_example()
print static_example()
print static_example()
0
Thomas Corll

J'ai connu le même problème. L'une des réponses à votre question m'a amené à l'idée suivante (qui a finalement fonctionné). J'utilise Python 3.7.

    # just an example 
    def func(): # define a function
       func.y = 4 # here y is a local variable, which I want to access; func.y defines 
                  # a method for my example function which will allow me to access 
                  # function's local variable y
       x = func.y + 8 # this is the main task for the function: what it should do
       return x

    func() # now I'm calling the function
    a = func.y # I put it's local variable into my new variable
    print(a) # and print my new variable

Ensuite, je lance ce programme dans Windows PowerShell et je reçois la réponse 4 . Conclusion: pour pouvoir accéder à la variable d'une fonction locale, vous pouvez ajouter le nom de la fonction et un point devant le nom de la variable locale (puis, bien sûr, utiliser cette construction pour appeler la variable à la fois dans le corps de la fonction et à l'extérieur. de celui-ci). J'espère que cela aidera. 

0