我的黑客解决方案如下。我非常欢迎你的评论。
我有一个类,它在指定的时间范围内(称为PerformanceAnalysisMixin
)处理给定对象组的性能计算。例如:
class PerformanceAnalysisMixin(object):
def set_time_frame(self, time_frame):
sets up time frame and sources related info
def return_over_time_frame(self, time_frame='past_year', values_only=False):
return value if values_only else return ('ABC', values)
class Performance(object):
# a mythical object which returns the values of calls to
# PerformanceAnalyisMixin() as if they were properties
# where the calls in are the form: name_for_method.arg0.arg1
>>> pam = PerformanceAnalysisMixin()
>>> pam.set_time_frame((2010, 2013)) # data for the past three years
>>> pam.return_over_time_frame('past_year', values_only=True)
0.13
>>> pam.return_over_time_frame('past_3_years', values_only=True)
0.25
我希望能够以非常惯用的方式调用结果,而不是针对类实例的方法。例如:
>>> perf = Performance(pam)
>>> # 'time_frame_return' is the name for the method 'return_over_time_frame'
>>> perf.time_frame_return.past_year
0.13
>>> perf.time_frame_return.past_3_years
0.25
如果只有几个方法和几个默认时间帧,这将很容易硬编码,但我希望有足够的抽象,所以我不需要编写许多排列。我想使用属性调用为最终方法调用指定适当的参数。
在我开始创建这种类型的解决方案之前,我正在寻找指导。如果我愿意的话,我可以预先填充一个字典,但我宁愿在运行时调用该方法。
我的黑客攻击解决方案:
class F(object):
def __init__(self, name, fn=None):
self.name = name
self.arg_names = [self.name]
self.fn = fn
def __getattr__(self, key):
self.key = F(key)
self.arg_names.append(self.key.name)
if key == 'res':
_res = self.fn(*self.arg_names[:-1])
self.res = _res
return _res
return self
>>> f = F('get', fn=(lambda a, b, c, d: (a, b, c, d)))
>>> r = f.some.more.stuff
>>> r.res
('get', 'some', 'more', 'stuff')
>>> g = F('one', fn=(lambda a, b, c, d: (a, b, c, d)))
>>> g.more.time.ftw.res
('one', 'more', 'time', 'ftw')
答案 0 :(得分:1)
您可以执行以下操作:
class MapProperty2Argument(object):
def __init__(self, fn):
self.fn = fn
def __getattr__(self, name):
return self.fn(name)
class Performance(object):
@property
def time_frame_return(self):
return MapProperty2Argument(
PerformanceAnalysisMixin().return_over_time_frame)
当然,您可能不希望为每个函数调用创建PerformanceAnalysisMixin
对象,但需要一些现有的实例。
答案 1 :(得分:1)
我想你想沿着这些方向做点什么:
class PamSugar(object):
""" Here be dragons """
def __init__(self, pam):
self.pam = pam
def __getattr__(self, key):
# will be called if the key attribute is not found in usual places
# http://docs.python.org/2/reference/datamodel.html#object.__getattr__
# Better make sure key is allowed (you have to define the sanitizer)
if not is_good_property_name(key):
raise AttributeError("Can't handle that")
return self.pam.return_over_time_frame(key, values_only=True)
class Performance(object):
""" perf.sugar.past_year """
def __init__(self, pam):
self.sugar = PamSugar(pam)