我正在写一个其他人使用的库。
对于每个重要的功能,我都有一个基类。用户应该将这些子类化,并添加他们的重要方法版本。
现在我想我需要添加一个“setup()”函数,该函数必须在子类的 init ()之后运行,但是Problem
已经存在不同的子类,我不想让人们触摸那些。
我也在2.7上发展。
说:
class Problem:
def __init__(self,**kwargs):
#this and that
def setup(self,**kwargs):
#Generic stuff that needs to be done after SpecificProblem.__init__() is called.
class SpecificProblem(Problem):
def __init__(self,**kwargs):
Problem.__init__(self,**kwargs)
#this and that
答案 0 :(得分:8)
不应让子类覆盖__init__
,而应让他们编写一个名为make
的方法。如:
class Problem:
def __init__(self,**kwargs):
self.make(**kwargs)
self.setup(**kwargs)
def setup(self,**kwargs):
#Generic stuff that needs to be done after SpecificProblem.__init__() is called.
def make(self,**kwargs):
# method to be overwritten by subclasses
pass
class SpecificProblem(Problem):
def make(self,**kwargs):
#this and that
这个问题有不同的方法。如果您希望编写SpecificProblem的人负责完成所有操作以及完成任务,那么元类方法就有意义。但是,如果你想要适当地“分开关注点”,那么我的方式允许你这样做。
答案 1 :(得分:4)
gabe的回答是你应该使用的,但这是一个适合元类的问题;没有进一步阐述:
class SetupClass(type):
def __call__(cls, *args, **kwargs):
# create the instance as normal. this will invokoe the class's
# __init__'s as expected.
self = super(SetupClass, cls).__call__(*args, **kwargs)
# this steps through the MRO in ascending order (so that child
# classes can be confident their bases are "set up"). A corresponding
# teardown() method should probably be `reversed(cls.__mro__)`
for base in cls.__mro__:
setup = vars(base).get('setup')
# in the general case, we have to use the descriptor protocol
# to setup methods/staticmethods/classmethods properly
if hasattr(setup, '__get__'):
setup = setup.__get__(self, cls)
if callable(setup):
setup()
return self
class A(object):
__metaclass__ = SetupClass
def __init__(self):
print "A.__init__"
def setup(self):
print "A.setup"
class B(A):
def __init__(self):
print "B.__init__"
super(B, self).__init__()
>>> B()
B.__init__
A.__init__
A.setup
答案 2 :(得分:0)
只需拨打Problem.setup
__init__
中的SpecificProblem
即可
class SpecificProblem(Problem):
def __init__(self,**kwargs):
Problem.__init__(self,**kwargs)
#this and that
Problem.setup(self, **kwargs)
你应该真正在python中使用新式的类,因为它们是python 3.x中的默认类。
class Problem(object):
def __init__(self, **kwargs):
pass
def setup(self, **kwargs):
pass
class SpecificProblem(Problem):
def __init__(self, **kwargs):
super(SpecificProblem, self).__init__(**kwargs)
# In python three, super().__init__(**kwargs) works.
super(SpecificProblem, self).setup(**kwargs)