我很抱歉,标题不太清楚,我想不出一种用句子来描述我的问题的方法。我正在python2.7中构建一些代码,如下所述。
最小的工作示例
我的代码有一个Parameter
类,该类实现了name
和value
之类的属性,
class Parameter(object):
def __init__(self,name,value=None,error=None,dist=None,prior=None):
self.name = name
self._value = value # given value for parameter,this is going to be changed very often in an MCMC sampler
self.error = error # initial estimate of error for the parameter,will only be set once
self._dist = dist # a distribution for the parameter,will only be set once
self.prior = prior
@property
def value(self):
return self._value
@property
def dist(self):
return self._dist
该类还具有一些属性,如果给出分布,它们将返回Parameter.dist
的均值,中位数等。
我还有另一堂课,例如ParameterSample
,将创建一组不同的Parameter
对象。这些Parameter
对象中的某些对象具有使用value
函数设置的属性(例如error
,Parameter.set_parameter()
),而其他Parameter
对象未明确设置,但是它们的value
和dist
属性依赖取决于其他设置的其他Parameter
对象:
class ParameterSample(object):
def __init__(self):
varied_parameters = ('a','b') # parameter names whose `value` attribute is varied
derived_parameters = ('c',) # parameter names whose `value` attribute is varied,but depends on `a.value` and `b.value`
parameter_names = varied_parameters + derived_parameters
# create `Parameter` objects for each parameter name
for name in parameter_names:
setattr(self,Parameter(name))
def set_parameter(self,**kwargs):
for key,val in kwargs.items():
if key == 'value':
key = '_'.join(['',key]) # add underscore to set `Parameter._value`
setattr(getattr(self,name),key,val) # basically does e.g. `self.a.value = 1`
我现在可以创建一个ParameterSample
并像这样使用它们:
parobj = ParameterSample()
parobj.set_parameter('a',value=1,error=0.1)
parobj.set_parameter('b',value=2,error=0.5)
parobj.a.value
>>> 1
parobj.b.error
>>> 0.5
parobj.set_parameter('b',value=3)
parobj.b.value
>>> 3
parobj.b.error
>>> 0.5
我想要的
我最终想要的是以相同的方式使用Parameter.c
。例如:
parobj.c.value
>>> 4 # returns parobj.a.value + parobj.b.value
parobj.c.dist
>>> None # returns a.dist + b.dist,but since they are not currently set it is None
c
因此必须是一个Parameter
对象,该对象具有与a
和b
相同的属性,但是其value
和{{1} }根据dist
和a
的当前属性进行更新。
但是,我还应该提到我希望能够为参数b
设置允许的优先范围,例如c
对其值进行任何调用之前,因此parobj.set_parameter('c',prior=(0,10))
必须是创建c
对象时已经定义的Parameter
对象。
如何将其实现到我的ParameterSample
类中?
我尝试过的
我试图研究制作自己的装饰器,但是我不确定这是否可行,因为我不完全了解如何使用它们。
我还考虑过在ParameterSample
上添加@property来在每次调用时创建一个新的c
对象,但是我觉得这不是可行的方法,因为它可能会减慢速度代码。
我还应该注意,上面的Parameter
类将在另一个类中继承,因此无论采用什么解决方案,都应能够在此设置中使用它:
ParameterSample