orientada - llamar metodo de otra clase python
Variables dentro y fuera de una clase__init__() función (5)
Estoy tratando de entender, ¿hay alguna diferencia entre estas clases además del nombre? ¿Hay alguna diferencia si uso o no uso la función __init __ () al declarar la variable "valor"?
class WithClass ():
def __init__(self):
self.value = "Bob"
def my_func(self):
print(self.value)
class WithoutClass ():
value = "Bob"
def my_func(self):
print(self.value)
Mi principal preocupación es que lo usaré de una manera cuando eso me cause problemas más adelante (actualmente uso la llamada init).
Además de la respuesta de S.Lott, las variables de clase se pasan al nuevo método de metaclases y se puede acceder a ellas a través del diccionario cuando se define una metaclase. Por lo tanto, se puede acceder a las variables de clase incluso antes de crear e instanciar las clases.
por ejemplo:
class meta(type):
def __new__(cls,name,bases,dicto):
# two chars missing in original of next line ...
if dicto[''class_var''] == ''A'':
print ''There''
class proxyclass(object):
class_var = ''A''
__metaclass__ = meta
...
...
El conjunto de variables fuera de __init__
pertenece a la clase. Son compartidos por todas las instancias.
Variables creadas dentro de __init__
(y todas las demás funciones del método) y precedidas por self.
pertenecer a la instancia del objeto.
Me gustaría agregar algo a las respuestas que leí en este hilo y este hilo (que hace referencia a este).
Descargo de responsabilidad : estas observaciones provienen de los experimentos que corrí
Variables fuera de __init__
:
Estas son, de hecho, variables de clase estáticas y, por lo tanto, son accesibles para todas las instancias de la clase.
Variables dentro de __init__
:
El valor de estas variables de instancia solo está disponible para la instancia en cuestión (a través de la self
referencia)
Mi contribución :
Una cosa que los programadores deben tener en cuenta al usar variables de clase estáticas es que pueden ser sombreadas por variables de instancia (si está accediendo a las variables de clase estáticas a través de la self
referencia).
Explicación
Previamente, pensé que ambas formas de declarar las variables eran exactamente las mismas (tonto), y eso fue en parte porque podía acceder a ambos tipos de variables a través de la self
referencia. Ahora, cuando tuve problemas, investigué el tema y lo aclare.
El problema de acceder a variables de clase estáticas a través de la self
referencia es que solo hace referencia a la variable de clase estática si no hay una variable de instancia con el mismo nombre, y para empeorar las cosas, intentar redefinir una variable de clase estática a través de la self
referencia no funcionan porque se crea una variable de instancia que luego sombrea la variable de clase estática previamente accesible.
Para evitar este problema, siempre debe hacer referencia a las variables de clase estáticas a través del nombre de la clase.
Ejemplo :
#!/usr/bin/env python
class Foo:
static_var = ''every instance has access''
def __init__(self,name):
self.instance_var = ''I am '' % name
def printAll(self):
print ''self.instance_var = %s'' % self.instance_var
print ''self.static_var = %s'' % self.static_var
print ''Foo.static_var = %s'' % Foo.static_var
f1 = Foo(''f1'')
f1.printAll()
f1.static_var = ''Shadowing static_var''
f1.printAll()
f2 = Foo(''f2'')
f2.printAll()
Foo.static_var = ''modified class''
f1.printAll()
f2.printAll()
Salida :
self.instance_var = I am f1
self.static_var = every instance has access
Foo.static_var = every instance has access
self.instance_var = I am f1
self.static_var = Shadowing static_var
Foo.static_var = every instance has access
self.instance_var = I am f2
self.static_var = every instance has access
Foo.static_var = every instance has access
self.instance_var = I am f1
self.static_var = Shadowing static_var
Foo.static_var = modified class
self.instance_var = I am f2
self.static_var = modified class
Foo.static_var = modified class
Espero que esto sea útil para alguien
Sin uno mismo
Crea algunos objetos:
class foo(object):
x = ''original class''
c1, c2 = foo(), foo()
Puedo cambiar la instancia de c1 y no afectará la instancia de c2:
c1.x = ''changed instance''
c2.x
>>> ''original class''
Pero si cambio la clase foo, todas las instancias de esa clase también se cambiarán:
foo.x = ''changed class''
c2.x
>>> ''changed class''
Tenga en cuenta cómo funciona el alcance de Python aquí:
c1.x
>>> ''changed instance''
Con uno mismo
Cambiar la clase no afecta las instancias:
class foo(object):
def __init__(self):
self.x = ''original self''
c1 = foo()
foo.x = ''changed class''
c1.x
>>> ''original self''
class User(object):
email = ''none''
firstname = ''none''
lastname = ''none''
def __init__(self, email=None, firstname=None, lastname=None):
self.email = email
self.firstname = firstname
self.lastname = lastname
@classmethod
def print_var(cls, obj):
print ("obj.email obj.firstname obj.lastname")
print(obj.email, obj.firstname, obj.lastname)
print("cls.email cls.firstname cls.lastname")
print(cls.email, cls.firstname, cls.lastname)
u1 = User(email=''abc@xyz'', firstname=''first'', lastname=''last'')
User.print_var(u1)
En el código anterior, la clase User tiene 3 variables globales, cada una con el valor ''none''. u1 es el objeto creado al crear una instancia de esta clase. El método print_var imprime el valor de las variables de clase de la clase Usuario y las variables de objeto del objeto u1. En el resultado que se muestra a continuación, cada una de las variables de clase User.email
, User.firstname
y User.lastname
tiene el valor ''none''
, mientras que las variables de los objetos u1.email
, u1.firstname
y u1.lastname
tienen los valores ''abc@xyz''
, ''first''
y ''last''
.
obj.email obj.firstname obj.lastname
(''abc@xyz'', ''first'', ''last'')
cls.email cls.firstname cls.lastname
(''none'', ''none'', ''none'')