2015-09-04 3 views
1

Lorsque je suis passé de JavaScript à Python, j'ai remarqué que je n'avais pas trouvé de moyen d'ajouter des propriétés aux classes de types de données. Par exemple, en JavaScript, si je voulais être capable de taper arr.last et avoir retourne le dernier élément du tableau arr, ou tapez arr.last = 'foo' et pour définir le dernier élément à 'foo', je voudrais utiliser:L'équivalent Python de `Object.defineProperty()` JavaScript `

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"] 

Cependant, en Python, je ne sais pas comment faire l'équivalent de Object.defineProperty(X.prototype,'propname',{get:function(){},set:function(){}});

note: Je suis pas demander comment faire la fonction exemple spécifique, je suis en train de pouvoir définir une propriété avec get et set sur les types de données primitives (str, int, float, liste, dict, jeu, etc.)

+0

Peut-être que vous voulez lire sur les [types standards] (https: // docs. python.org/3/library/stdtypes.html)? Vous pouvez faire cela directement en Python, sans entrave. En d'autres termes, en essayant de définir les propriétés et les getters/setters, vous avez probablement un [XY Problem] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – TigerhawkT3

Répondre

0

Si je vous ai bien compris, vous souhaitez modifier des classes existantes (méthode ajouter) Vérifiez ce fil Python: changing methods and attributes at runtime

+0

Je ne suis pas sûr si je comprends bien ce post, mais il semble que cela crée une nouvelle classe qui peut avoir ses attributs modifiés, par opposition à ce que je veux (pouvoir modifier les attributs d'une classe qui a été définie avec Python (par exemple, int) – Cyoce

+0

@Cyoce Toutes les classes ne sont pas égales en Python, en grande partie à cause des considérations de performance/implémentation – user2864740

2

Voir la documentation de la fonction property. Il a des exemples. Ce qui suit est le résultat d'print property.__doc__ sous 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 
+0

Cela n'ajoute pas de fonctionnalité existante à l'exécution, comme OP demandé. – Mego

4

En Python 2 , l'ajout de nouveaux attributs (aka objets membres, y compris les méthodes) à une classe nouvelle de style (qui dérive de object) est aussi facile que de les définir simplement:

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 

J'utilise le property que Dan D. builtin mentionné dans his answer, mais en fait l'attribut ayants après la classe est créée, comme la question demande.

Online demo

1: en Python 3, il est encore plus simple, puisque toutes les classes sont des classes nouveau style