简体   繁体   中英

Python 3.6: abc.abstracmethod on classmethod no check on class level call

With python 3.6, When I decorate an abstractmehod with abc.abstractmethod withing a class having metaclass=abc.ABCMeta , the abstract method can be called from a class (not instance) point of view.

It seems that the abc decorators are performing the checks when the class is instanciated, so it is not done when calling from instance.

This behavior is highly disturbing and it looks like a bug in the abc module.

What did I miss?

Thanks

Code example:

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}")

Results:

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

This behavior is consistent with the behavior described in the documentation for @classmethod .

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

"It can be called either on the class (such as Cf()) or on an instance (such as C().f())."

In this case, it can't be called on an instance because it is abstract, but since it's a classmethod, it is still okay to call it on the class directly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM