【发布时间】:2021-01-29 08:44:39
【问题描述】:
我是元类的新手,可能会以意想不到的方式使用它们。我很困惑isinstance() 方法在处理子类时似乎具有传递行为,但在处理元类时却没有。
第一种情况:
class A(object):
pass
class B(A):
pass
class C(B):
pass
ic = C()
暗示isinstance(ic,X) 为真,X 等于 A、B 或 C。
另一方面,这是一个元类示例:
class DataElementBase(object):
def __init__(self,value):
self.value = self.__initialisation_function__(value)
class MetaDataElement(type):
def __new__(cls,name,initialisation_function, helptext ):
result = type.__new__(cls,name,(DataElementBase,), dict(help=helptext) )
result.__initialisation_function__ = staticmethod(initialisation_function)
return result
### test code ####
# create a class from the metaclass
MyClass = MetaDataElement( 'myclass', float, "Value is obtained as float of user input" )
# create an instance of the class
my_instance = MyClass( '4.55' )
print ( 'MyClass is instance of MetaDataElement? %s' % isinstance( MyClass, MetaDataElement ) )
print ( 'MyClass is instance of DataElementBase? %s' % isinstance( MyClass, DataElementBase ) )
print ( 'my_instance is instance of MyClass? %s' % isinstance( my_instance, MyClass ) )
print ( 'my_instance is instance of MetaDataElement? %s' % isinstance( my_instance, MetaDataElement ) )
print ( 'my_instance is instance of DataElementBase? %s' % isinstance( my_instance, DataElementBase ) )
产量:
MyClass is instance of MetaDataElement? True
MyClass is instance of DataElementBase? False
my_instance is instance of MyClass? True
my_instance is instance of MetaDataElement? False
my_instance is instance of DataElementBase? True
也就是说,MyClass 是 MetaDataElement 元类的实例,my_instance 是 MyClass 类的实例,但不是 MetaDataElement 的实例。
我的解释正确吗?对此有简单的解释吗?
【问题讨论】:
-
因为子类是相关类型。元类是类型的类型。不是一回事,你不应该期望实例是 metaclass 的实例,它是 class 的实例,而类是元类。
-
是的,您的解释是正确的。定义上是真的;子类化与元类不同(因此名称不同)。简单来说
my_instance有MyClass类型,没有MetaDataElement类型,所以不是MetaDataElement的实例。 -
这里没有惊喜。由于您已经回答了自己的问题,因此不确定除了“是”之外任何人都可以给出什么有用的答案。
-
好的,问题不清楚。我已将 jsbueno 的答案标记为正确,因为它添加了更多上下文,帮助我了解更多。