Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

189
Vistas
Redefinir el método de un objeto

Tengo una clase, donde un método solo debe ejecutarse una vez. Por supuesto, podría hacerse fácilmente con el indicador artificial has_executed = True/False , pero ¿por qué usarlo, si simplemente puede eliminar el método en sí? python es un lenguaje tipo pato, todo es una referencia, bla-bla-bla , ¿qué puede salir mal?

Al menos era el pensamiento. En realidad no pude hacerlo:

 class A: def b(self): print("empty") self.__delattr__('b') a = A() ab()

plantea AttributeError: b . Sin embargo, ejecutar self.__getattribute__('b') devuelve <bound method Ab of <__main__.A object at 0x000001CDC6742FD0>> , lo que me suena estúpido: ¿por qué un method es diferente de un attribute , ya que todo en python es solo un referencia a un objeto? ¿Y por qué puedo __getattribute__ , pero no __delattr__ ?

Lo mismo ocurre con la redefinición. Puedo configurar fácilmente cualquier atributo, pero ¿los métodos son un no-no?

 class A: def b(self): print("first") self.__setattr__('b', lambda self: print(f"second")) a = A() ab() ab()

da como resultado TypeError: <lambda>() missing 1 required positional argument: 'self' . Lo que, por supuesto, significa que ahora python no está usando la notación de puntos como se pretendía. Por supuesto, podríamos deshacernos del atributo self en la lambda por completo, considerando que ya tenemos la referencia en b . ¿Pero no es incorrecto por diseño?

Cuanto más trato de llevar python al límite, más me frustro. Algunas limitaciones impuestas ( ¿o aparentemente impuestas? ) parecen tan antinaturales, considerando la forma en que se comercializa el idioma. ¿No debería permitir esto? ¿Por qué no funciona?

UPD

Bien, considera esto:

 class A: def __init__(self): self.variable = 1 def b(self): print("old") self.variable += 1 def new_b(): print("new") self.variable += 15 self.__setattr__('b', new_b)

Funcionará y hará lo que queramos: ninguno de los otros objetos tendrá su método Ab redefinido una vez que un objeto superponga su definición b . ( superposiciones , ya que hasta ahora todos dicen que no se puede redefinir un método para un objeto, sino que solo se oculta de la persona que llama detrás de otro atributo con el mismo nombre, según tengo entendido).

¿Es esto bueno?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

No funciona porque b no es un atributo perteneciente a la instancia, pertenece a la clase. Por lo tanto, no puede eliminarlo en la instancia porque no está allí para eliminarse.

 >>> a = A() >>> list(a.__dict__) [] >>> list(A.__dict__) ['__module__', 'b', '__dict__', '__weakref__', '__doc__']

Cuando se evalúa ab , Python verá que a no tiene un atributo de instancia llamado b y recurrirá a la clase. (Es un poco más complicado porque al volver a la clase, no devolverá simplemente el método en sí, sino una versión del método que está vinculado a la instancia a ).

Dado que no desea eliminar el método en la clase, el camino a seguir es reemplazar el método en la instancia. No sé por qué intentaste hacer esto con __setattr__ ; no hay necesidad de eso, simplemente asigna self.b = ... como de costumbre. La razón por la que falló su intento es porque su lambda requiere un parámetro posicional llamado self , pero este parámetro no se vinculará automáticamente a la instancia cuando lo busque, porque es un atributo de instancia, no un atributo de clase.

 class A: def b(self): print('first') self.b = lambda: print('second')

Uso:

 >>> a = A() >>> ab() first >>> ab() second
over 4 years ago · Santiago Trujillo Denunciar

0

Bueno, en python tienes 2 tipos de atributos

  • Un atributo de clase es una variable que pertenece a una determinada clase y no a un objeto en particular. Cada instancia de esta clase comparte la misma variable. Estos atributos generalmente se definen fuera del constructor init
  • Un instance/object attribute es una variable que pertenece a un (y solo uno) objeto. Cada instancia de una clase apunta a sus propias variables de atributos. Estos atributos se definen dentro del constructor init .

En el caso de un atributo de clase, es parte del descriptor de clase, por lo que no puede eliminarlo de los atributos de objeto como self.__deleteattr__ o agregar uno nuevo con __setattr__ ya que altera el descriptor de clase y se refleja en todos los objetos. Tal operación puede tener efectos devastadores.

Es muy similar a una variable de clase también. Sin embargo, puede cambiar el comportamiento anulando o reasignando como se muestra a continuación.

 class A: def b(self): print("empty") Ab = lambda self: print(f"second") a = A() ab() ab()
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda