poo - self python 3
¿Cómo evitar el "yo" explícito en Python? (10)
De hecho, puedes usar la receta "Yo implícito" de la presentación de Armin Ronacher "5 años de malas ideas" (google it).
Es una receta muy ingeniosa, como casi todo de Armin Ronacher, pero no creo que esta idea sea muy atractiva. Creo que preferiría explicitar esto en C # / Java.
Actualizar. Enlace a "receta de mala idea": https://speakerdeck.com/mitsuhiko/5-years-of-bad-ideas?slide=58
He estado aprendiendo Python siguiendo algunos tutoriales de pygame .
Allí encontré un uso extensivo de la palabra clave self , y proveniente de un fondo principalmente de Java, encuentro que sigo olvidando escribir self . Por ejemplo, en lugar de self.rect.centerx
escribiría rect.centerx
, porque, para mí, rect ya es una variable miembro de la clase.
El paralelo de Java que se me ocurre para esta situación es tener que prefijar todas las referencias a las variables miembro con esto .
¿Estoy atrapado prefijando todas las variables de miembro consigo mismo , o hay una forma de declararlas que me permitiría evitar tener que hacerlo?
Incluso si lo que sugiero no es pitónico , me gustaría saber si es posible.
He echado un vistazo a estas preguntas relacionadas, pero no responden del todo lo que busco:
De: Self Hell - Más funciones de estado.
... un enfoque híbrido funciona mejor. Todos los métodos de su clase que realmente hacen cálculos deben moverse a cierres, y las extensiones para limpiar la sintaxis deben mantenerse en clases. Rellena los cierres en clases, tratando la clase como un espacio de nombres. Los cierres son funciones esencialmente estáticas, por lo que no requieren selfs *, incluso en la clase ...
El "yo" es el marcador de posición convencional de la instancia de objeto actual de una clase. Se usa cuando desea hacer referencia a la propiedad o campo o método del objeto dentro de una clase como si se estuviera refiriendo a "sí mismo". Pero para hacerlo más corto, alguien en el reino de la programación de Python comenzó a usar "self", otros reinos usan "this" pero lo hacen como una palabra clave que no puede ser reemplazada. Prefiero usar "its" para aumentar la legibilidad del código. Es una de las cosas buenas de Python: tienes libertad para elegir tu propio marcador de posición para la instancia del objeto que no sea "self". Ejemplo para uno mismo:
class UserAccount():
def __init__(self, user_type, username, password):
self.user_type = user_type
self.username = username
self.password = encrypt(password)
def get_password(self):
return decrypt(self.password)
def set_password(self, password):
self.password = encrypt(password)
Ahora reemplazamos ''self'' con ''its'':
class UserAccount():
def __init__(its, user_type, username, password):
its.user_type = user_type
its.username = username
its.password = encrypt(password)
def get_password(its):
return decrypt(its.password)
def set_password(its, password):
its.password = encrypt(password)
que es mas legible ahora?
En realidad, self
no es una palabra clave, es solo el nombre dado convencionalmente al primer parámetro de los métodos de instancia en Python. Y ese primer parámetro no se puede omitir, ya que es el único mecanismo que tiene un método para saber a qué instancia de su clase está siendo llamado.
Las respuestas anteriores son básicamente variantes de "no se puede" o "no se debe". Si bien estoy de acuerdo con este último sentimiento, la pregunta técnicamente aún no ha recibido respuesta.
Además, hay razones legítimas por las cuales alguien podría querer hacer algo en la línea de lo que la pregunta real está haciendo. Una cosa con la que me tropiezo es a veces largas ecuaciones matemáticas donde el uso de nombres largos hace que la ecuación sea irreconocible. Aquí hay algunas maneras de cómo puedes hacer esto en un ejemplo enlatado:
import numpy as np
class MyFunkyGaussian() :
def __init__(self, A, x0, w, s, y0) :
self.A = float(A)
self.x0 = x0
self.w = w
self.y0 = y0
self.s = s
# The correct way, but subjectively less readable to some (like me)
def calc1(self, x) :
return (self.A/(self.w*np.sqrt(np.pi))/(1+self.s*self.w**2/2)
* np.exp( -(x-self.x0)**2/self.w**2)
* (1+self.s*(x-self.x0)**2) + self.y0 )
# The correct way if you really don''t want to use ''self'' in the calculations
def calc2(self, x) :
# Explicity copy variables
A, x0, w, y0, s = self.A, self.x0, self.w, self.y0, self.s
sqrt, exp, pi = np.sqrt, np.exp, np.pi
return ( A/( w*sqrt(pi) )/(1+s*w**2/2)
* exp( -(x-x0)**2/w**2 )
* (1+s*(x-x0)**2) + y0 )
# Probably a bad idea...
def calc3(self, x) :
# Automatically copy every class vairable
for k in self.__dict__ : exec(k+''= self.''+k)
sqrt, exp, pi = np.sqrt, np.exp, np.pi
return ( A/( w*sqrt(pi) )/(1+s*w**2/2)
* exp( -(x-x0)**2/w**2 )
* (1+s*(x-x0)**2) + y0 )
g = MyFunkyGaussian(2.0, 1.5, 3.0, 5.0, 0.0)
print(g.calc1(0.5))
print(g.calc2(0.5))
print(g.calc3(0.5))
El tercer ejemplo - es decir, usar for k in self.__dict__ : exec(k+''= self.''+k)
es básicamente lo que la pregunta en realidad está pidiendo, pero déjenme aclarar que no creo que sea generalmente una buena idea.
Para obtener más información y formas de iterar a través de variables de clase, o incluso funciones, consulte las respuestas y la discusión de esta pregunta . Para una discusión de otras formas de nombrar dinámicamente variables, y por qué esto generalmente no es una buena idea, vea esta publicación en el blog .
Puede usar el nombre que desee, por ejemplo
class test(object):
def function(this, variable):
this.variable = variable
o incluso
class test(object):
def function(s, variable):
s.variable = variable
pero estás atrapado con el uso de un nombre para el alcance.
No recomiendo que utilices algo diferente a ti mismo a menos que tengas una razón convincente, ya que sería extraño para pythonistas con experiencia.
Sí, el yo es tedioso. Pero, ¿es mejor?
class Test:
def __init__(_):
_.test = ''test''
def run(_):
print _.test
sí, siempre debe especificarse a self
, porque explícito es mejor que implícito, según la filosofía de Python.
También descubrirá que la forma en que programa en python es muy diferente de la forma en que programa en Java, por lo tanto, el uso del self
tiende a disminuir porque no se proyecta todo dentro del objeto. Por el contrario, usted hace un mayor uso de la función de nivel de módulo, que puede ser mejor probado.
por cierto. Lo odié al principio, ahora odio lo opuesto. lo mismo para control de flujo controlado por indentación.
self es parte de la sintaxis de python para acceder a los miembros de los objetos, así que me temo que estás atascado
Python requiere especificar uno mismo. El resultado es que nunca hay confusión sobre qué es miembro y qué no, incluso sin la definición de clase completa visible. Esto conduce a propiedades útiles, como: no puede agregar miembros que sombrean accidentalmente a los no miembros y, por lo tanto, descifrar el código.
Un ejemplo extremo: puede escribir una clase sin ningún conocimiento de las clases base que podría tener, y siempre saber si está accediendo a un miembro o no:
class A(some_function()):
def f(self):
self.member = 42
self.method()
Ese es el código completo ! (some_function devuelve el tipo utilizado como base).
Otro, donde los métodos de una clase se componen dinámicamente:
class B(object):
pass
print B()
# <__main__.B object at 0xb7e4082c>
def B_init(self):
self.answer = 42
def B_str(self):
return "<The answer is %s.>" % self.answer
# notice these functions require no knowledge of the actual class
# how hard are they to read and realize that "members" are used?
B.__init__ = B_init
B.__str__ = B_str
print B()
# <The answer is 42.>
Recuerda que estos dos ejemplos son extremos y no los verás todos los días, ni sugiero que a menudo debas escribir códigos como este, pero muestran claramente aspectos de ser explícitamente necesarios.