简体   繁体   中英

Python equivalent of JavaScript's `Object.defineProperty()`

As I transition from JavaScript to Python, I noticed I haven't figured out a way to add properties to the data type classes. For example, in JavaScript, if I wanted to be able to type arr.last and have it return the last element in the array arr , or type arr.last = 'foo' and to set the last element to 'foo' , I would use:

Object.defineProperty(Array.prototype,'last',{
    get:function(){
        return this[this.length-1];
    },
    set:function(val){
        this[this.length-1] = val;
    }
});

var list = ['a','b','c'];
console.log(list.last); // "c"
list.last = 'd';
console.log(list); // ["a","b","d"]

However, in Python, I'm not sure how to do the equivalent of Object.defineProperty(X.prototype,'propname',{get:function(){},set:function(){}});

Note: I am not asking for how to do the specific example function, I am trying to be able to define a property with a get and set onto the primitive data types (str, int, float, list, dict, set, etc.)

In Python 2 1 , adding new attributes (aka member objects, including methods) to a new-style class (one that derives from object ) is as easy as simply defining them:

class Foo(object):
    def __init__(self):
        self._value = "Bar"

def get_value(self):
    return self._value

def set_value(self, val):
    self._value = val

def del_value(self):
    del self._value

Foo.value = property(get_value, set_value, del_value)
f = Foo()

print f.value
f.value = "Foo"
print f.value

I use the property builtin that Dan D. mentioned in his answer , but this actually assigns the attribute after the class is created, like the question asks.

Online demo

1: in Python 3, it's even simpler, since all classes are new-style classes

See the documentation of the property function. It has examples. The following is the result of print property.__doc__ under Python 2.7.3:

property(fget=None, fset=None, fdel=None, doc=None) -> property attribute

fget is a function to be used for getting an attribute value, and likewise
fset is a function for setting, and fdel a function for del'ing, an
attribute.  Typical use is to define a managed attribute x:
class C(object):
    def getx(self): return self._x
    def setx(self, value): self._x = value
    def delx(self): del self._x
    x = property(getx, setx, delx, "I'm the 'x' property.")

Decorators make defining new properties or modifying existing ones easy:
class C(object):
    @property
    def x(self): return self._x
    @x.setter
    def x(self, value): self._x = value
    @x.deleter
    def x(self): del self._x

如果我理解正确,那么您想编辑现有的类(添加方法)检出此线程Python:在运行时更改方法和属性

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM