Ámbitos variables en clases de Python
Declarar una variable en una clase (fuera de una función): todas las funciones de la clase pueden acceder a ella (básicamente una variable pública)
Declarar una variable dentro de una función dentro de una clase: solo esa función puede acceder a ella (está en el alcance de esa función)
Declarar una variable self.(variable name)
dentro de una función dentro de una clase: todas las funciones de la clase pueden acceder a ella (¿en qué se diferencia esto de global (variable name)
?)
Y como no hay privado/protegido, todo es público, por lo que todo lo que se puede acceder desde dentro de una clase es accesible desde fuera de la clase.
¿Hay algún otro matiz que deba saber o ya lo he entendido?
Como el listado de tu pregunta no es 100% claro, he decidido explicarlo con un ejemplo sencillo. También incluye algunas cosas como __something
variables que no mencionaste en tu lista.
class Test:
a = None
b = None
def __init__(self, a):
print self.a
self.a = a
self._x = 123
self.__y = 123
b = 'meow'
Al principio, a
y b
son solo variables definidas para la clase misma, accesibles a través de Test.a
y Test.b
no específicas de ninguna instancia.
Al crear una instancia de esa clase (lo que resulta en __init__
su ejecución):
print self.a
no encuentra una variable de instancia y por lo tanto devuelve la variable de claseself.a = a
a
: se crea una nueva variable de instancia . Esto oculta la variable de clase, por lo queself.a
ahora hará referencia a la variable de instancia; para acceder a la variable de clase ahora tienes que usarTest.a
- La asignación a
self._x
crea una nueva variable de instancia. Se considera "no parte de la API pública" (también conocida como protegida), pero técnicamente no tiene un comportamiento diferente. - La asignación a
self.__y
crea una nueva variable de instancia llamada_Test__y
, es decir, su nombre está alterado, por lo que, a menos que utilice el nombre alterado, no se puede acceder a él desde fuera de la clase. Esto podría usarse para variables "privadas". - La asignación a
b
crea una variable local. No está disponible desde ningún otro lugar excepto la__init__
función, ya que no se guarda en la instancia, clase o alcance global.
Declarar una variable en el nivel superior de la clase es como declarar una variable estática o de clase. Calificarlo con self es declarar una variable de instancia. Las variables de clase se pueden modificar haciendo referencia a ellas por el nombre de la clase (p. ej. Class.x = 5
) y todas las instancias heredarán estos cambios. Las variables de instancia son privadas de una instancia y solo pueden ser modificadas por esa instancia.
Puede lograr cierto nivel de control de acceso utilizando guiones bajos. Vea variables privadas en el tutorial de Python . Por convención, las variables que comienzan con un guión bajo, por ejemplo, _foo
son partes no públicas de una API, y los nombres que comienzan con dos guiones bajos, por ejemplo, __foo
tendrán su nombre modificado para ser _classname__foo
.
Aunque respondida, déjame agregar algunos comentarios a tus preguntas:
Declarar una variable en una clase (fuera de una función): todas las funciones de la clase pueden acceder a ella (básicamente una variable pública)
Es como una variable estática y se puede llamar usando el nombre de la clase. Estas variables están disponibles para todas las funciones, cualquier función puede modificarlas e imprimirlas.
Declarar una variable dentro de una función dentro de una clase: solo esa función puede acceder a ella (está en el alcance de esa función):
Si la variable se declara sin self
ella, solo será accesible dentro de esa función, como una variable local. Sin embargo, si se declaró usando self
like self.var= 'somevalue'
, entonces se puede acceder a él a través de cualquier objeto, pero no a través del nombre de la clase.
Declarar una variable
self.(variable name)
dentro de una función dentro de una clase: todas las funciones de la clase pueden acceder a ella (¿en qué se diferencia esto deglobal (variable name)
?)
Ver respuesta en la parte anterior.
Y como no hay privado/protegido, todo es público, por lo que todo lo accesible desde dentro de una clase es accesible desde fuera de la clase.
Sí, pero podemos usar un guión bajo único para decirle al mundo que esta variable es privada, pero técnicamente eso no la hace privada.