Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

448
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda