我创建了一个包含 3 个主要内容的模块:
- 具有方法的主类
__new__
和继承该方法的子类; make_method
可以将方法关联到现有类的装饰器:
def make_method(obj):
'''Decorator to make the function a method of *obj*.
In the current context::
@make_method(Axes)
def toto(ax, ...):
...
makes *toto* a method of `Axes`, so that one can directly use:
ax.toto()
COPYRIGHT: from Yannick Copin
'''
def decorate(f):
setattr(obj, f.__name__, f)
return f
return decorate
- 一个
generic
班。
主类有一个__new__
方法,该方法使用make_method
装饰器创建适用于任何子类的绘图函数。这是示例:
class MainClass():
FREEPARAMETERS = ['mu_1', 'sigma_1']
PLTALL = ["self.param['" + k + "']" for k in FREEPARAMETERS]
def __new__(cls, *arg, **kwargs):
'''Returns the class with dynamically generated methods'''
obj = super(MainClass, cls).__new__(cls)
exec("@make_method(MainClass)\n" +
"def plot_a(self, x_lin):\n" +
" return self.likelihood_tot(x_lin, %s)"
% (", ".join(MainClass.PLTALL)))
return(obj)
然后,如果我以ChildClass
这种方式创建:
class ChildClass(MainClass):
FREEPARAMETERS = ['mu_1', 'sigma_1', 'mu_2', 'sigma_2']
PLTALL = ["self.param['" + k + "']" for k in FREEPARAMETERS]
它将有一个plot_a
方法,只需要一个,x_lin
而不必手动输入参数(提供一个likelihood_tot
采用正确参数的方法)。
所有这些都非常有效(对于我真正需要的东西来说,这可能有点矫枉过正,但它很甜蜜)。然后generic
上课:
class generic():
'''Usage:
gen = MyModule.generic()
gen.set_model('model')
fitted_model_1 = gen.fit(dataset1)
fitted_model_2 = gen.fit(dataset2)
fitted_model_1.plot_a(x_lin)
fitted_model_2.plot_a(x_lin)'''
def set_model(self, classname):
'''Associates an uninstantiated class to self.model from its string'''
self.model = getattr(sys.modules[__name__], classname)
def fit(self, dataset, **kwargs):
'''Instantiates the class with the pandas,
apply the `minimize` method,
and gives that back as an output'''
model = self.model(dataset)
model.minimize(**kwargs)
return(model)
正如其文档中所述,这个想法是能够调用一个通用模型,例如,我可以将不同的数据集传递给该模型,而不必每次都手动实例化该类。工作正常。
执行以下操作时会出现问题,在哪里ChildClass1
并ChildClass2
有不同FREEPARAMETERS
:
gen.set_model('ChildClass1')
fitted_childclass1 = gen.fit(dataset)
gen.set_model('ChildClass2')
fitted_childclass2 = gen.fit(dataset)
fitted_childclass2.plot_a(x_lin)
fitted_childclass1.plot_a(x_lin)
第一个plot_a(x_lin)
与generic
类的最后一次调用相关联,工作正常。然而,第二个根据最新实例类和之前实例类之间的相对数量给我一个KeyError: 'mu_2'
或一个,这意味着不知何故,动态生成的now 具有 的参数。TypeError: likelihood_tot() missing n required positional arguments
FREEPARAMETERS
plot_a
fitted_childclass1
fitted_childclass2
然而,当调用childclass1.PLTALL
or时childclass2.PLTALL
,我确实得到了预期的结果。似乎它们在实例化后没有互换。所有不是动态生成的方法都是正确的。
我当然可以调用plot_a
每个函数之间的函数,但这显然不是重点。我想要两者childclass1
并且childclass2
表现得好像我实例化它们一样:
childclass1 = MyModule.ChildClass1(dataset)
childclass1.minimize()
childclass2 = MyModule.ChildClass2(dataset)
childclass2.minimize()