python 重命名的方法,Python:即时重命名方法名称

我有许多文件使用具有以下语法的类:

o = module.CreateObject()

a = o.get_Field

现在实现已从’get_XXX’和’set_XXX’变为’XXX’:

o = module.CreateObject()

a = o.Field

这个实现是一个外部包,我不想改变.是否有可能编写一个包装器,它将动态拦截所有对’get_XXX’的调用,然后将其替换为新名称’XXX’的调用?

o = MyRenamer(module.CreateObject())

a = o.get_Field # works as before, o.Field is called

a = o.DoIt() # works as before, o.DoIt is called

它需要拦截所有调用,而不仅仅是有限的字段集,根据方法名称决定是否修改它并导致调用具有修改名称的方法.

解决方法:

如果要继续在已切换到使用属性的对象上使用get_Field和set_Field(您只需访问或分配给Field),则可以使用包装器对象:

class NoPropertyAdaptor(object):

def __init__(self, obj):

self.obj = obj

def __getattr__(self, name):

if name.startswith("get_"):

return lambda: getattr(self.obj, name[4:])

elif name.startswith("set_"):

return lambda value: setattr(self.obj, name[4:], value)

else:

return getattr(self.obj, name)

如果您使用额外的语法(如对象的索引或迭代),或者您需要使用isinstance识别对象的类型,则会出现问题.

更复杂的解决方案是创建一个名称重写的子类,并强制对象使用它.这不完全是一个包装,因为外部代码仍将直接处理对象(因此魔术方法和isinstance)将按预期工作.这种方法适用于大多数对象,但对于具有花哨的元类魔法的类型以及某些内置类型可能会失败:

def no_property_adaptor(obj):

class wrapper(obj.__class__):

def __getattr__(self, name):

if name.startswith("get_"):

return lambda: getattr(self, name[4:])

elif name.startswith("set_"):

return lambda value: setattr(self, name[4:], value)

else:

return super(wrapper, self).__getattr__(name)

obj.__class__ = wrapper

return obj

标签:python,dynamic,decorator

来源: https://codeday.me/bug/20190620/1244344.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值