我正在研究一些遗留代码(由喜欢意大利面条代码的人创建),它有超过150个吸气剂和超过150个安装者.吸气剂看起来像这样:
def GetLoadFee(self):
r_str = ""
if len(self._LoadFee) > 20:
r_str = self._LoadFee[:20]
else:
r_str = self._LoadFee.strip()
return r_str.strip()
def GetCurrency(self):
r_str = ""
if len(self._Currency) > 3:
r_str = self._Currency[:3]
else:
r_str = self._Currency.strip()
return r_str.strip()
Run Code Online (Sandbox Code Playgroud)
我希望获取每个Getter的内容,并将它们放入装饰器/闭包或其他一些方法,以使这些代码更容易维护.Setters都是一个衬垫,因此它们并不重要.但它们基本上都是一样的.有什么想法可以减轻痛苦吗?
注意:我仍然需要原始的Getter名称,因为它们在其他程序中使用,因为这个讨厌的脚本被用在许多其他遗留代码中.
aba*_*ert 11
def make_generic_getter(name, maxlen):
def getter(self):
value = getattr(self, name)
r_str = ""
if len(value) > maxlen:
r_str = value[:maxlen]
else:
r_str = value.strip()
return r_str.strip()
return getter
Run Code Online (Sandbox Code Playgroud)
现在,你可以这样做:
class Foo(object):
def __init__(self):
self._Bar = 'abc'
self._Baz = 'def'
GetBar = make_generic_getter('_Bar', 5)
GetBaz = make_generic_getter('_Baz', 2)
Run Code Online (Sandbox Code Playgroud)
然后:
>>> f = Foo()
>>> f.GetBar()
'abc'
>>> f.GetBaz()
'de'
Run Code Online (Sandbox Code Playgroud)
显然,原始功能中还有许多重复和不必要的东西.(并且为您的属性使用PEP8样式的名称会好得多.)但显然,比其他方式更容易重构,然后改进.(换句话说,从这里开始,但不要停在这里.)
来自评论:
方法制作者如何获得"自我"参考?
方法制作者实际上没有得到self参考.self调用方法制作者时没有参考.但是,self在定义类时,也没有引用正常方法的参考.在任何一种情况下,你只是定义一个函数self作为它的第一个参数,并且self当你调用它时它会以某种方式神奇地获得适当的参数.
要真正理解这实际上是如何工作的,您需要了解描述符.请参阅实现描述符和调用描述符(或3.3版本),阅读几次,看看@property装饰器是如何实现的,在交互式解释器中玩,放弃,进入睡眠状态,明天再试一次,它应该全部点击.但是如果你先学习魔法版本会更容易,所以让我们这样做,使用一个更简单的例子:
>>> def func(self): pass
>>> class C(object):
... def meth(self): pass
... fake1 = func
>>> C.fake2 = func
>>> func, C.meth, C.fake1, C.fake2
(<function __main__.func>, <unbound method C.meth>, <unbound method C.func>, <unbound method C.func>)
Run Code Online (Sandbox Code Playgroud)
一个未绑定的方法只是im_class持有它的类,im_func持有正常函数和im_self持有的东西None.当你fake1 = func在类定义中,或者C.fake2 = func在事实之后,你实际上并没有将func自己作为fake1or 的值fake2,但是当一个未绑定的方法被包围时func,它im_class指向它C.
>>> c = C()
>>> c.meth, c.fake1
(<bound method C.meth of <__main__.C object at 0x111ebb0d0>>, <bound method C.meth of <__main__.C object at 0x111ebb0d0>>)
Run Code Online (Sandbox Code Playgroud)
当您获取类的实例时,其所有未绑定的方法都将成为绑定方法.如果你看一下绑定方法的属性,它们是一样的非绑定方法,只是im_self是c不是None.当你打电话时c.fake1(),它就是这样运作的 - Python认为这c.fake1是一个绑定方法,所以实际上它调用了c.fake1.im_func(c.fake1.im_self).这就是如何fake获得自我参数.
(这在Python 3中变得更加简单,因为不再有未绑定的方法,但我认为你更关心Python 2,因为你正在处理大量的遗留代码.)