【发布时间】:2019-07-24 20:46:12
【问题描述】:
假设我有一个带有 t 属性的 Python 类型。我想创建一个“参数化元类型”,以便以下工作:
class MySuperClass(type):
pass
class MySubClass(MySuperClass):
# Here is the problem -- How do I define types that contain stuff,
# independent of an object?
def __init__(self, t): # Or __getitem__
self.t = t
def __instancecheck__(self, instance):
return isinstance(instance, MySubClass) and instance.t == self.t
def __subclasscheck__(self, subclass):
return MySubClass in subclass.__mro__ and subclass.t == self.t
class MyObject(metaclass=MySubClass):
def __init__(self, t):
self.t = t
# Test code:
## Both of these, square brackets work too
assert isinstance(MyObject(0), MySubClass(0))
assert not isinstance(MyObject(0), MySubClass(1))
## Ideally
assert isinstance(MyObject(0), MySuperClass) or isinstance(MyObject(0), MySubClass)
目前我收到以下错误:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-99ad08881526> in <module>
14 return MySubClass in subclass.__mro__ and subclass.t == self.t
15
---> 16 class MyObject(metaclass=MySubClass):
17 def __init__(self, t):
18 self.t = t
TypeError: __init__() takes 2 positional arguments but 4 were given
【问题讨论】:
-
空
MySuperClass有什么意义?你不能删除它并做class MySubClass(type)吗? -
@Sanya 如果没有
MySuperClass可以做到,并且assert isinstance(MyObject(0), MySubClass)有效,我可以没有MySuperClass。如果可能的话,我可以编辑我原来的问题。查看测试的最后一行。 -
我认为您可能需要在您的层次结构中的某处定义
__new__。 -
@snakecharmerb 我在
MySubClass上定义了__new__,并在__init__和__new__中调用了基类方法(当然是原始签名)。没用,抱怨第一个参数必须是类型而不是int。 -
你真的需要
isinstance(MyObject(0), MySuperClass)吗?它将使MyObject成为type的后代,这对于非元类来说很奇怪。
标签: python metaprogramming metaclass