在 Class 构造期间正确实现方法继承
Properly Implement Method Inheritance During Class Construction
如何在 class 完全构建之前调用的方法中实现类似超类的行为。我可以实现这样一系列相互依赖的方法吗?
from six import with_metaclass
class Meta(type):
"""a metaclass"""
def __init__(cls, name, bases, classdict):
cls.setup_class()
def setup_class(cls):
pass
class A(with_metaclass(Meta, object)):
"""a class"""
@classmethod
def instantiate(cls, name):
print("instantiating through '%s'" % name)
@classmethod
def setup_class(cls):
cls.instantiate('A')
class B(A):
@classmethod
def setup_class(cls):
super(B, cls).setup_class()
cls.instantiate('B')
class C(B) pass
显然这行不通,因为调用 setup_class
时 B
并不正确存在。
- related question
这个问题我问了很久,但一直找不到 post 来解释 metaclasses 的这个方面。事实上,我拥有它已经很久了,以至于我想出了这个替代方案,但最终是不必要的,solution。从技术上讲,它完全符合我想要的那种语法(这很酷),但最终它是一种 hack。由于我花了这么长时间编写毫无意义(但仍然很酷)的代码,我想我至少会尝试确保没有其他人陷入同样的困境。
我的困惑实际上源于我没有完全扩展我对 metaclasses 的理解,以及它们与它们的 classes 之间的关系,从而得出合乎逻辑的结论。所以,事实证明,创建我想要的那种继承的最好方法实际上是在一系列元 classes 中执行它——出于同样的原因,试图通过 [=] 的实例继承属性18=] 没有意义,使 metaclass 的实例多态化没有意义:
from six import with_metaclass
class Meta(type):
"""a metaclass"""
def __init__(cls, name, bases, classdict):
print("Beginning '%s' setup" % name)
cls.setup_class()
print("Finished '%s' setup \n" % name)
def setup_class(cls):
cls.attribute = 0
cls.instantiate('Meta')
class AMeta(Meta):
def setup_class(cls):
super(AMeta, cls).setup_class()
cls.instantiate('A')
def instantiate(cls, name):
print("instantiating through '%s'" % name)
class A(with_metaclass(AMeta, object)): pass
class BMeta(AMeta):
def setup_class(cls):
super(BMeta, cls).setup_class()
cls.instantiate('B')
class B(with_metaclass(BMeta, object)): pass
class C(B): pass
如果有人愿意更彻底地检查这个,我相信有人会很感激。
如何在 class 完全构建之前调用的方法中实现类似超类的行为。我可以实现这样一系列相互依赖的方法吗?
from six import with_metaclass
class Meta(type):
"""a metaclass"""
def __init__(cls, name, bases, classdict):
cls.setup_class()
def setup_class(cls):
pass
class A(with_metaclass(Meta, object)):
"""a class"""
@classmethod
def instantiate(cls, name):
print("instantiating through '%s'" % name)
@classmethod
def setup_class(cls):
cls.instantiate('A')
class B(A):
@classmethod
def setup_class(cls):
super(B, cls).setup_class()
cls.instantiate('B')
class C(B) pass
显然这行不通,因为调用 setup_class
时 B
并不正确存在。
- related question
这个问题我问了很久,但一直找不到 post 来解释 metaclasses 的这个方面。事实上,我拥有它已经很久了,以至于我想出了这个替代方案,但最终是不必要的,solution。从技术上讲,它完全符合我想要的那种语法(这很酷),但最终它是一种 hack。由于我花了这么长时间编写毫无意义(但仍然很酷)的代码,我想我至少会尝试确保没有其他人陷入同样的困境。
我的困惑实际上源于我没有完全扩展我对 metaclasses 的理解,以及它们与它们的 classes 之间的关系,从而得出合乎逻辑的结论。所以,事实证明,创建我想要的那种继承的最好方法实际上是在一系列元 classes 中执行它——出于同样的原因,试图通过 [=] 的实例继承属性18=] 没有意义,使 metaclass 的实例多态化没有意义:
from six import with_metaclass
class Meta(type):
"""a metaclass"""
def __init__(cls, name, bases, classdict):
print("Beginning '%s' setup" % name)
cls.setup_class()
print("Finished '%s' setup \n" % name)
def setup_class(cls):
cls.attribute = 0
cls.instantiate('Meta')
class AMeta(Meta):
def setup_class(cls):
super(AMeta, cls).setup_class()
cls.instantiate('A')
def instantiate(cls, name):
print("instantiating through '%s'" % name)
class A(with_metaclass(AMeta, object)): pass
class BMeta(AMeta):
def setup_class(cls):
super(BMeta, cls).setup_class()
cls.instantiate('B')
class B(with_metaclass(BMeta, object)): pass
class C(B): pass
如果有人愿意更彻底地检查这个,我相信有人会很感激。