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

442
Vistas
Comportamiento extraño al mezclar el método abstracto, el método de clase y los decoradores de propiedades.

He estado tratando de ver si se puede crear una propiedad de clase abstracta mezclando los tres decoradores (en Python 3.9.6, si eso importa), y noté un comportamiento extraño.

Considere el siguiente código:

 from abc import ABC, abstractmethod class Foo(ABC): @classmethod @property @abstractmethod def x(cls): print(cls) return None class Bar(Foo): @classmethod @property def x(cls): print("this is executed") return super().x

Esto produce

 this is executed <class '__main__.Bar'>

Esto significa que, de alguna manera, Bar.x termina siendo llamado.

PyCharm me advierte que la Property 'self' cannot be deleted . Si invierto el orden de @classmethod y @property , no se llama a Bar.x , pero sigo recibiendo la misma advertencia, y también otra: This decorator will not receive a callable it may expect; the built-in decorator returns a special object (esto también aparece cada vez que coloco @property encima de @classmethod ).

Eliminar cualquiera de los tres decoradores (con los cambios apropiados: agregar () al eliminar @property o cambiar cls a self al eliminar @classmethod ) también evita que se llame a Bar.x

Supongo que todo esto significa que probablemente sea una mala idea mezclar directamente esos decoradores (como se indica en la discusión sobre las propiedades de clase en otros hilos aquí).

Sin embargo, tengo curiosidad: ¿qué está pasando aquí? ¿Por qué se llama Bar.x?

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

0

Puede intentar generar una excepción en Bar.x De esta manera se puede ver donde se llama.

Debería llevarlo a abc.py en la biblioteca estándar, específicamente a la línea _abc_init(cls) . Esta función está implementada en C. Una de las primeras cosas que hace es llamar a compute_abstract_methods(self) verificar todos los métodos abstractos que la clase ha heredado para ver si están implementados. Esto significa obtener Bar.x que invoca el captador de propiedades.

over 4 years ago · Santiago Trujillo Denunciar

0

Esto parece un error en la lógica que verifica los métodos abstractos heredados.

Un objeto en una clase dict se considera abstracto si recuperar su atributo __isabstractmethod__ produce True . Cuando Bar crea una subclase de Foo , Python necesita determinar si Bar anula el Foo.x abstracto y, de ser así, si la anulación es en sí misma abstracta. Debería hacer esto buscando en el MRO una entrada 'x' en un dictado de clase, de modo que pueda examinar __isabstractmethod__ en los descriptores directamente sin invocar el protocolo del descriptor, pero en su lugar, realiza un acceso de atributo Bar.x simple .

El acceso al atributo Bar.x invoca la propiedad de clase. También devuelve None en lugar de la propiedad abstract, y None no es abstracto, por lo que Python se confunde acerca de si Bar.x es abstracto. Python termina pensando que Bar.x es abstracto debido a una verificación diferente, pero si cambia un poco el ejemplo:

 >>> from abc import ABC, abstractmethod >>> >>> class Foo(ABC): ... @classmethod ... @property ... @abstractmethod ... def x(cls): ... print(cls) ... return None ... >>> class Bar(Foo): pass ... <class '__main__.Bar'> >>> Bar() <__main__.Bar object at 0x7f46eca8ab80>

Python termina pensando que Bar es una clase concreta, aunque el ejemplo modificado no anula x en absoluto.

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