gpt4 book ai didi

python - 如何在 Python 中重构 100 多个类方法?

转载 作者:太空狗 更新时间:2023-10-29 20:12:47 24 4
gpt4 key购买 nike

我正在处理一些具有超过 150 个 getter 和超过 150 个 setter 的遗留代码(由热爱意大利面条代码的人创建)。 setter/getter 看起来像这样:

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()

我很乐意获取这些 Getters 中的每一个的内容,并将它们放入装饰器/闭包或其他一些方法中,以使此代码更易于维护。二传手都是一个类轮,所以他们不那么重要。但它们基本上也都是一样的。有什么想法可以减轻这种痛苦吗?

注意:我仍然需要原始的 Getter 名称,因为它们在其他程序中使用,因为这个讨厌的脚本在许多其他遗留代码中使用。

最佳答案

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

现在,您可以这样做:

class Foo(object):
def __init__(self):
self._Bar = 'abc'
self._Baz = 'def'
GetBar = make_generic_getter('_Bar', 5)
GetBaz = make_generic_getter('_Baz', 2)

然后:

>>> f = Foo()
>>> f.GetBar()
'abc'
>>> f.GetBaz()
'de'

显然,原始函数中还有很多重复和不必要的东西。 (并且为您的属性使用 PEP8 样式名称会好得多。)但显然,先重构再改进比反过来要容易得多。 (换句话说,从这里开始,但不要在这里停止。)

来自评论:

How does the method maker get the "self" reference?

方法制定者实际上并没有得到 self引用。没有 self在调用方法生成器时获取的引用。但是也没有self在定义类时引用获取普通方法。在任何一种情况下,您都只是定义一个接受 self 的函数。作为它的第一个参数,它以某种方式神奇地获得了适当的 self当你调用它时。

要真正了解这实际上 是如何工作的,您需要了解描述符。参见 Implementing Descriptors和 Invoking Descriptors(或 3.3 版本),多读几遍,看看 @property 是如何实现的decorator实现了,在interactive interpreter里玩玩,放弃, sleep ,明天再试,应该都点击了。但是如果你先学习魔法版本会更容易,所以让我们用一个更简单的例子来做:

>>> 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>)

未绑定(bind)的方法只是一个带有 im_class 的东西持有它的类,一个im_func持有一个正常的功能,一个im_self控股None .当你做 fake1 = func在类定义中,或 C.fake2 = func事实上,你实际上并没有以 func 结束。本身作为 fake1 的值或 fake2 , 但用一个未绑定(bind)的方法包裹 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>>)

当你获取一个类的实例时,它所有未绑定(bind)的方法都变成绑定(bind)方法。如果您查看绑定(bind)方法的属性,它们与未绑定(bind)方法相同,除了 im_self。是c而不是 None .当你调用 c.fake1() ,这就是它的工作原理——Python 看到 c.fake1是一个绑定(bind)方法,所以实际上它调用了 c.fake1.im_func(c.fake1.im_self) .这就是fake获取自身参数。

(这一切在 Python 3 中变得更简单,因为不再有未绑定(bind)方法这样的东西,但我假设您更关心 Python 2,因为您正在处理大量遗留代码。)

关于python - 如何在 Python 中重构 100 多个类方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14287935/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com