Manipulación de nombres en Python

En el proceso de modificación de nombres, cualquier identificador con dos guiones bajos al principio y un guión bajo al final se reemplaza textualmente con _classname__identifierel nombre de clase que es el nombre de la clase actual. Significa que cualquier identificador de la forma __geek (al menos dos guiones bajos iniciales o como máximo un guión bajo final) se reemplaza con _classname__geek, donde classname es el nombre de la clase actual sin los guiones bajos iniciales.

Ejemplo:

# Python program to demonstrate
# name mangling
  
  
class Student:
    def __init__(self, name):
        self.__name = name
  
    def displayName(self):
        print(self.__name)
  
s1 = Student("Santhosh")
s1.displayName()
  
# Raises an error
print(s1.__name)

Producción

Santhosh
Traceback (most recent call last):
  File "/home/be691046ea08cd2db075d27186ea0493.py", line 14, in 
    print(s1.__name)
AttributeError: 'Student' object has no attribute '__name'

En el ejemplo anterior, la variable de clase __nameno es accesible fuera de la clase. Solo se puede acceder dentro de la clase. Cualquier modificación de la variable de clase se puede hacer solo dentro de la clase.

Proceso de manipulación de nombres

Con la ayuda del dir()método, podemos ver el proceso de cambio de nombre que se realiza a la variable de clase. El proceso de modificación del nombre fue realizado por el Intérprete. El dir()método se usa pasando el objeto de clase y devolverá todos los atributos válidos que pertenecen a ese objeto.

# Python program to demonstrate
# name mangling
  
  
class Student:
    def __init__(self, name):
        self.__name = name
  
s1 = Student("Santhosh")
print(dir(s1))

Producción

[‘_Estudiante__nombre’, ‘__clase__’, ‘__delattr__’, ‘__dict__’, ‘__dir__’, ‘__doc__’, ‘__eq__’, ‘__format__’, ‘__ge__’, ‘__getattribute__’, ‘__gt__’, ‘__hash__’, ‘ __init__’, ‘__le__’, ‘__lt__’, ‘__module__’, ‘__ne__’, ‘__new__’, ‘__reduce__’, ‘__reduce_ex__’, ‘__repr__’, ‘__setattr__’, ‘__sizeof__’, ‘__str__’, ‘__subclasshook__’ , ‘__referencia débil__’]

El resultado anterior muestra el dir()método que devuelve todos los atributos válidos con el proceso de modificación de nombres que se realiza en la variable de clase __name. El nombre cambió de __name a _Student__name.

Accediendo a variables alteradas de nombre

El proceso de modificación de nombres ayuda a acceder a las variables de clase desde fuera de la clase. Se puede acceder a las variables de clase agregando _classname. El nombre mangling es el más cercano a privado, no exactamente privado.

# Python program to demonstrate
# name mangling
  
  
class Student:
    def __init__(self, name):
        self.__name = name
  
s1 = Student("Santhosh")
print(s1._Student__name)

Producción

Santhosh

Se accede a la variable de clase anterior al agregarle _classname. Se accede a la variable de clase desde fuera de la clase con el nombre _Student__name.

Manipulación de nombres con anulación de métodos

Debido a la manipulación de nombres, existe un soporte limitado para un caso de uso válido para miembros privados de clase básicamente para evitar conflictos de nombres con nombres definidos por subclases. Cualquier identificador de la forma __geek (al menos dos guiones bajos iniciales o como máximo un guión bajo final) se reemplaza con _classname__geek, donde classname es el nombre de la clase actual sin los guiones bajos iniciales. Siempre que ocurra dentro de la definición de la clase, esta manipulación está hecha. Esto es útil para permitir que las subclases anulen los métodos sin interrumpir las llamadas a métodos intraclase.
Veamos este ejemplo e intentemos averiguar cómo funciona este guión bajo:

Ejemplo:

# Python code to illustrate how mangling works 
# With method overriding
  
class Map: 
    def __init__(self): 
        self.__geek() 
          
    def geek(self): 
        print("In parent class") 
    
    # private copy of original geek() method 
    __geek = geek    
    
class MapSubclass(Map): 
        
    # provides new signature for geek() but 
    # does not break __init__() 
    def geek(self):         
        print("In Child class")
          
# Driver's code
obj = MapSubclass()
obj.geek()

Producción:

In parent class
In Child class

Publicación traducida automáticamente

Artículo escrito por Santhosh220897 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *