Python >> Tutoriel Python >  >> Python

Comment passer une variable par référence en Python ?

Résumé : Les variables sont transmises par référence d'objet en Python. Par conséquent, les objets mutables sont passés par référence tandis que les objets immuables sont passés par valeur en Python. Pour passer des objets immuables par référence, vous pouvez retourner et réaffecter la valeur à la variable , ou passez-le dans un dictionnaire/liste , ou créez une classe et utilisez la variable self comme référence.

Problème : Comment passer une variable par référence en Python ?

Afin d'utiliser des fonctions et des classes en Python ou dans tout autre langage de programmation, il est extrêmement important que nous comprenions comment fonctionne un appel de fonction basé sur un Appel par référence ou Appel par valeur ou Appel par objet Référence . Discutons de ces concepts un par un avant d'arriver à la solution finale.

Principes fondamentaux de l'appel par valeur

Dans la méthode appel par valeur , la valeur d'un argument est copiée dans le paramètre de la fonction. Par conséquent, toute modification apportée au paramètre à l'intérieur de la fonction appelée n'est pas reflétée dans les paramètres réels de la fonction appelante car la variable à l'intérieur de la fonction appelée et la fonction appelante font référence à deux emplacements différents dans la mémoire.

Exemple :

def func():
  a = 10
  print("Before Function call value of a = ",a)
  increment(a)
  print("After Function call is over value of a = ",a)
  print("Identity of a in func() is ",id(a))

def increment(k):
  a = k+10
  print("Inside function call Value of a = ",a)
  print("Identity of a in increment() is ",id(a))
  return a

func()

Sortie :

Before Function call value of a =  10
Inside function call Value of a =  20
Identity of a in increment() is  140578841094464
After Function call is over value of a =  10
Identity of a in func() is  140578841094144

Principes fondamentaux de l'appel par référence

Dans la méthode Appel par référence, l'adresse de l'argument est transmise à la fonction appelée. Ainsi, nous faisons référence à l'adresse de la variable dans ce cas et toute modification apportée au paramètre à l'intérieur de la fonction est également reflétée à l'extérieur de la fonction.

L'appel par référence est pris en charge par des langages tels que Java. Jetons un coup d'œil à un petit programme java pour visualiser le théorème de travail de la méthode d'appel par référence. ( J'utilise délibérément Java ici afin que nous puissions comparer et contraster les différences lorsque nous discutons Méthode d'appel par référence d'objet utiliser Python depuis un moment .)

public class Reference{  
 int data=10;  
 
 public static void main(String args[]){  
   Reference obj=new Reference();  
  
   System.out.println("before change "+obj.data);  
   obj.change(obj);//passing object  
   System.out.println("after change "+obj.data);  
  
 }
 
 void change(Reference obj){  
 obj.data=obj.data+100;//changes will be in the instance variable  
 }  
     
} 

Sortie :

before change 10
after change 110

Pour comprendre la différence avec les méthodes d'appel par référence et d'appel par valeur, veuillez consulter l'animation ci-dessous :

Principes de base de l'appel par référence d'objet

Beaucoup d'entre vous ont peut-être rencontré les méthodes d'appel par référence et d'appel par valeur d'appel de fonction, mais si vous êtes un débutant dans le monde de Python, alors probablement le terme Appel par référence d'objet est nouveau pour vous. Voici un rappel pour vous avant de discuter du fonctionnement des appels de fonction en Python :Tout est un objet en Python.

Python n'utilise ni l'appel par valeur ni l'appel par référence. Il utilise la référence d'appel par objet / l'appel par affectation, ce qui signifie :-

  • Lorsqu'un objet mutable comme une liste est passée à une fonction, elle effectue un appel par référence.
  • Lorsqu'un objet immuable comme un nombre, une chaîne ou un tuple est passé à une fonction, il effectue un appel par valeur.

Exemple :le programme suivant illustre le concept ci-dessus où Python effectue un appel par référence dans le cas d'objets modifiables comme des listes, tandis qu'un appel par valeur dans le cas d'un objet immuable comme une chaîne :-

def refer(l):
  l.append(5)
  print("list inside function : ",l)
  return l

def value(n):
  name = "Python"
  print("Name within function : ",name)
  return name
 
li = [1,2,3,4]
print("list before function return : ",li)
refer(li)
print("list after function return : ",li)
name = "Finxter"
print("Name before function return : ",name)
value(name)
print("Name after function return : ",name)

Sortie :

list before function return :  [1, 2, 3, 4]
list inside function :  [1, 2, 3, 4, 5]
list after function return :  [1, 2, 3, 4, 5]
Name before function return :  Finxter
Name within function :  Python
Name after function return :  Finxter

Cela nous amène à la question essentielle :

Comment passer une variable immuable par référence en Python ?

Ce ne sera pas un problème dans le cas d'objets mutables mais dans le cas d'objets immuables, nous devons sortir quelques astuces de notre poche pour les changer. Jetons un coup d'œil à certains d'entre eux dans la prochaine phase de notre article.

Méthode 1 :Renvoyez la nouvelle valeur et réaffectez

Une solution de contournement simple pour passer une variable immuable comme une chaîne par référence consiste à accepter la variable, à y apporter des modifications et à renvoyer la valeur. Après avoir renvoyé la variable, réaffectez à nouveau la valeur renvoyée par la fonction à la variable car elle se trouve en dehors de la portée locale de la fonction.

Cela peut être un peu déroutant, mais le code suivant vous éclairera :

def change(n):
    n = "Sayon"
    return n

name = "Shubham"
print("Name before function call is ", name)
name = change(name)
print("Name after function call is ", name)

Sortie :

Name before function call is  Shubham
Name after function call is  Sayon

Méthode 2 :transmission de valeurs immuables à l'aide de dictionnaires ou de listes

Maintenant, cette méthode est un petit hack pour traiter un passage par référence d'objets immuables. Étant donné que les dictionnaires Python sont des objets de type mappage et sont modifiables, vous pouvez définir vos variables immuables dans un dictionnaire, puis les transmettre à la fonction. Même si les listes ne sont pas utilisées pour le mappage d'objets, vous pouvez toujours les utiliser comme des dictionnaires car les éléments d'une liste sont accessibles à l'aide de leur index et les listes sont modifiables.

Voyons comment nous définissons une chaîne et un nombre et les transmettons comme référence à l'aide de la liste et du dictionnaire :

name = {'name': 'Christian'}
n = [4]
print("***Values Before Function Call***")
print("Name: ",name['name'])
print("Number: ",n[0])

def func(d):
  d['name'] = 'Mayer'

def foo(n):
  n[0] += 1

func(name)
foo(n)
print ("***Values After Function Call***")
print("Name: ",name['name'])
print("Number: ",n[0])

Sortie :

***Values Before Function Call***
Name:  Christian
Number:  4
***Values After Function Call***
Name:  Mayer
Number:  5

Méthode 3 :Utilisation du mot-clé Class And Self

Le mot clé self est utilisé pour accéder aux attributs d'instance. Nous pouvons définir des attributs dans __init__ puis modifiez leur valeur dans les méthodes d'instance.

Jetons un coup d'œil au programme suivant pour comprendre comment cela fonctionne pour nous :

class Changed:
    def __init__(self):
        self.var = 10
        print("Value before function call :",self.var)
        self.Change(self.var)
        print("Value after function call :",self.var)

    def Change(self,n):
        self.var = n+1

obj = Changed()

Sortie :

Value before function call : 10
Value after function call : 11

Conclusion

Voici les principaux points à retenir de cet article :-

  1. Principes de base de l'appel par valeur
  2. Principes de base de l'appel par référence.
  3. Principes de base de l'appel par référence d'objet en Python pour les objets mutables et immuables
  4. Méthodes pour transmettre des objets immuables par référence en Python.

J'espère que vous avez trouvé cet article utile. Veuillez vous abonner et rester à l'écoute pour d'autres articles intéressants à l'avenir !