为什么用 `@abstractmethod` 修饰的方法**NOT** 有一个 `__isabstractmethod__` 属性是 True?
Why do methods **NOT** decorated with `@abstractmethod` have an `__isabstractmethod__` attribute which is True?
考虑以下 class:
from abc import abstractmethod
class K:
@staticmethod
def sm(*args):
pass
@classmethod
def cm(*args):
pass
@abstractmethod
def am(*args):
pass
# instance method
def im(*args):
pass
为什么没有用 @abstractmethod
修饰的方法有一个设置为 True
的 __isabstractmethod__
属性?
要重现此内容,您可以运行以下代码:
# DON'T LET DESCRIPTORS' `__get__` methods be called!
# USE THE DICT!
K_dct = object.__getattribute__(K, '__dict__')
sm = K_dct['sm']
cm = K_dct['cm']
am = K_dct['am']
im = K_dct['im']
ms = [sm, cm, am, im]
def go_soul_searching(obj):
"""
:param obj:
:return: string containing all global labels pointing to `obj`
"""
g = globals()
ns = [n for n in g.keys() if g[n] is obj]
return '{' + ', '.join(ns[0:-1]) + ', ' + ns[-1] + '}'
print_nicely = lambda m, attrname: ''.join([str(x).ljust(25) for x in [
attrname,
str(hasattr(m, attrname))
]])
def inspect_method(m):
header = '\n' + go_soul_searching(m) + '\n'
print(header, end='')
for attrname in inspect_method.attrs:
print(print_nicely(m, attrname))
inspect_method.attrs = ['__call__', '__get__', '__set__', '__isabstractmethod__']
for m in ms:
inspect_method(m)
输出是:
{sm, m} # STATIC METHOD
__call__ False
__get__ True
__set__ False
__isabstractmethod__ True
{cm, m} # CLASS METHOD
__call__ False
__get__ True
__set__ False
__isabstractmethod__ True
{am, m} # ABSTRACT METHOD
__call__ True
__get__ True
__set__ False
__isabstractmethod__ True
{im, m} # INSTANCE METHOD
__call__ True
__get__ True
__set__ False
__isabstractmethod__ False
很简单,您打印了 hasattr
的结果。是的,他们有这个属性。但是您没有检查属性的值。
>>> hasattr(cm, '__isabstractmethod__')
True
>>> cm.__isabstractmethod__
False
>>> hasattr(sm, '__isabstractmethod__')
True
>>> sm.__isabstractmethod__
False
考虑以下 class:
from abc import abstractmethod
class K:
@staticmethod
def sm(*args):
pass
@classmethod
def cm(*args):
pass
@abstractmethod
def am(*args):
pass
# instance method
def im(*args):
pass
为什么没有用 @abstractmethod
修饰的方法有一个设置为 True
的 __isabstractmethod__
属性?
要重现此内容,您可以运行以下代码:
# DON'T LET DESCRIPTORS' `__get__` methods be called!
# USE THE DICT!
K_dct = object.__getattribute__(K, '__dict__')
sm = K_dct['sm']
cm = K_dct['cm']
am = K_dct['am']
im = K_dct['im']
ms = [sm, cm, am, im]
def go_soul_searching(obj):
"""
:param obj:
:return: string containing all global labels pointing to `obj`
"""
g = globals()
ns = [n for n in g.keys() if g[n] is obj]
return '{' + ', '.join(ns[0:-1]) + ', ' + ns[-1] + '}'
print_nicely = lambda m, attrname: ''.join([str(x).ljust(25) for x in [
attrname,
str(hasattr(m, attrname))
]])
def inspect_method(m):
header = '\n' + go_soul_searching(m) + '\n'
print(header, end='')
for attrname in inspect_method.attrs:
print(print_nicely(m, attrname))
inspect_method.attrs = ['__call__', '__get__', '__set__', '__isabstractmethod__']
for m in ms:
inspect_method(m)
输出是:
{sm, m} # STATIC METHOD
__call__ False
__get__ True
__set__ False
__isabstractmethod__ True
{cm, m} # CLASS METHOD
__call__ False
__get__ True
__set__ False
__isabstractmethod__ True
{am, m} # ABSTRACT METHOD
__call__ True
__get__ True
__set__ False
__isabstractmethod__ True
{im, m} # INSTANCE METHOD
__call__ True
__get__ True
__set__ False
__isabstractmethod__ False
很简单,您打印了 hasattr
的结果。是的,他们有这个属性。但是您没有检查属性的值。
>>> hasattr(cm, '__isabstractmethod__')
True
>>> cm.__isabstractmethod__
False
>>> hasattr(sm, '__isabstractmethod__')
True
>>> sm.__isabstractmethod__
False