在python中动态添加@property [英] Dynamically adding @property in python

查看:49
本文介绍了在python中动态添加@property的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我可以通过执行以下操作向对象动态添加实例方法:

I know that I can dynamically add an instance method to an object by doing something like:

import types
def my_method(self):
    # logic of method
# ...
# instance is some instance of some class
instance.my_method = types.MethodType(my_method, instance)

稍后我可以调用 instance.my_method() 并且 self 将被正确绑定并且一切正常.

Later on I can call instance.my_method() and self will be bound correctly and everything works.

现在,我的问题是:如何做完全相同的事情来获得用@property 装饰新方法会产生的行为?

Now, my question: how to do the exact same thing to obtain the behavior that decorating the new method with @property would give?

我猜是这样的:

instance.my_method = types.MethodType(my_method, instance)
instance.my_method = property(instance.my_method)

但是,这样做 instance.my_method 会返回一个属性对象.

But, doing that instance.my_method returns a property object.

推荐答案

property 描述符对象需要存在于 class 中,不是实例中,达到您想要的效果.如果您不想更改现有类以避免更改其他实例的行为,则需要创建一个每个实例类",例如:

The property descriptor objects needs to live in the class, not in the instance, to have the effect you desire. If you don't want to alter the existing class in order to avoid altering the behavior of other instances, you'll need to make a "per-instance class", e.g.:

def addprop(inst, name, method):
  cls = type(inst)
  if not hasattr(cls, '__perinstance'):
    cls = type(cls.__name__, (cls,), {})
    cls.__perinstance = True
    inst.__class__ = cls
  setattr(cls, name, property(method))

我正在用一个属性标记这些特殊的每个实例"类,以避免在您对同一个实例进行多次 addprop 调用时不必要地创建多个类.

I'm marking these special "per-instance" classes with an attribute to avoid needlessly making multiple ones if you're doing several addprop calls on the same instance.

请注意,与 property 的其他用途一样,您需要使用的类是 new-style(通常通过从 直接或间接继承获得object),不是古老的遗留样式(在 Python 3 中删除),默认情况下分配给没有基类的类.

Note that, like for other uses of property, you need the class in play to be new-style (typically obtained by inheriting directly or indirectly from object), not the ancient legacy style (dropped in Python 3) that's assigned by default to a class without bases.

这篇关于在python中动态添加@property的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆