Python 3.6: abc.abstracmethod для метода класса не проверяется при вызове на уровне класса

С питоном 3.6, когда я украшаю abstractmehod с abc.abstractmethod в рамках класса, имеющего metaclass=abc.ABCMetaабстрактный метод может быть вызван с точки зрения класса (не экземпляра).

Кажется, что abc декораторы выполняют проверки, когда создается экземпляр класса, поэтому это не делается при вызове из экземпляра.

Это поведение очень тревожно, и это похоже на ошибку в abc модуль.

Что я упустил?

Спасибо

Пример кода:

import abc
import sys

class P(metaclass=abc.ABCMeta):
    @classmethod
    @abc.abstractmethod
    def acm(cls):
        pass

class X(P):
    pass

print("P.acm()", file=sys.stderr)
try:
    P.acm()
    print("OK")
except Exception as e:
    print(f"KO: {e}")

print("P().acm()", file=sys.stderr)
try:
    P().acm()
    print("OK")
except Exception as e:
    print(f"KO: {e}")

Результаты:

P.acm()
OK
P().acm()
KO: Can't instantiate abstract class P with abstract methods acm

1 ответ

Решение

Такое поведение согласуется с поведением, описанным в документации для @classmethod,

https://docs.python.org/3.6/library/functions.html?highlight=classmethod

"Он может быть вызван либо для класса (например, Cf ()), либо для экземпляра (например, C (). F ())".

В этом случае он не может быть вызван для экземпляра, потому что он абстрактный, но, поскольку это метод класса, все еще можно вызывать его непосредственно в классе.

Другие вопросы по тегам