Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Attributs de classe calculés

15 réponses
Avatar
Alex Marandon
Bonjour,

Je n'ai pas trouvé dans Python 2.5 de façon de déclarer des attributs de
classe calculés. Ai-je mal cherché ?

J'ai imaginé les implémenter en lecture seule de cette manière:



class classproperty(object):
def __init__(self, func):
self.func = func

def __get__(self, instance, owner):
return self.func(owner)

class Foo(object):
@classproperty
def bar(cls):
return "Je suis un attribut de " + cls.__name__

print Foo.bar



Voyez-vous des problèmes potentiels avec cette implémentation ?

Merci.

10 réponses

1 2
Avatar
Bruno Desthuilliers
Alex Marandon a écrit :
Bonjour,

Je n'ai pas trouvé dans Python 2.5 de façon de déclarer des attributs de
classe calculés. Ai-je mal cherché ?



Oui et non, selon ta définition de "attributs de classe calculés". Pour
une définition de "attribut calculé" == property, alors non, tu n'a pas
mal cherché.

J'ai imaginé les implémenter en lecture seule de cette manière:

class classproperty(object):
def __init__(self, func):
self.func = func

def __get__(self, instance, owner):
return self.func(owner)

class Foo(object):
@classproperty
def bar(cls):
return "Je suis un attribut de " + cls.__name__

print Foo.bar


Voyez-vous des problèmes potentiels avec cette implémentation ?



>>> Foo.bar = 42
>>> Foo.bar
42
>>>

Si tu veux éviter ce problème potentiel (à considérer que c'en soit
un...) et être plus 'fidèle' au fonctionnement du type property,
implémente aussi __set__.
Avatar
Christophe
Alex Marandon a écrit :
Bonjour,

Je n'ai pas trouvé dans Python 2.5 de façon de déclarer des attributs de
classe calculés. Ai-je mal cherché ?




Peut-être ce serait possible en créant des simples property dans une
metaclass?
Avatar
Bruno Desthuilliers
Christophe a écrit :
Alex Marandon a écrit :
Bonjour,

Je n'ai pas trouvé dans Python 2.5 de façon de déclarer des attributs
de classe calculés. Ai-je mal cherché ?




Peut-être ce serait possible en créant des simples property dans une
metaclass?



Tiens, j'y avais pas pensé... Par contre - si ça fonctionne, mais bon,
ça devrait, ya pas de raison -, ça implique a priori que ces propriétés
ne se seront accessible que depuis la classe - pas depuis une instance.
Avatar
Alex Marandon
Bruno Desthuilliers wrote:
Alex Marandon a écrit :
Bonjour,

Je n'ai pas trouvé dans Python 2.5 de façon de déclarer des attributs
de classe calculés. Ai-je mal cherché ?



Oui et non, selon ta définition de "attributs de classe calculés". Pour
une définition de "attribut calculé" == property, alors non, tu n'a pas
mal cherché.



Par curiosité, à quelle autre définition penses-tu ?

J'ai imaginé les implémenter en lecture seule de cette manière:
class classproperty(object):
def __init__(self, func):
self.func = func

def __get__(self, instance, owner):
return self.func(owner)

class Foo(object):
@classproperty
def bar(cls):
return "Je suis un attribut de " + cls.__name__

print Foo.bar


Voyez-vous des problèmes potentiels avec cette implémentation ?



>>> Foo.bar = 42
>>> Foo.bar
42
>>>

Si tu veux éviter ce problème potentiel (à considérer que c'en soit
un...) et être plus 'fidèle' au fonctionnement du type property,
implémente aussi __set__.



J'ai essayé, mais __set__, contrairement à __get__, n'est pas appellé
lorsqu'on accède à l'attribut sur la classe:
<http://docs.python.org/ref/descriptors.html>.
Avatar
Alex Marandon
Bruno Desthuilliers wrote:
Christophe a écrit :
Alex Marandon a écrit :
Bonjour,

Je n'ai pas trouvé dans Python 2.5 de façon de déclarer des attributs
de classe calculés. Ai-je mal cherché ?




Peut-être ce serait possible en créant des simples property dans une
metaclass?



Tiens, j'y avais pas pensé... Par contre - si ça fonctionne, mais bon,
ça devrait, ya pas de raison -, ça implique a priori que ces propriétés
ne se seront accessible que depuis la classe - pas depuis une instance.



Effectivement:


class PropertyMeta(type):
def __init__(self, name, bases, dict):
self.name = name

@property
def bar(self):
return 'Je suis un attribut de ' + self.name


class Foo(object):
__metaclass__ = PropertyMeta

print Foo.bar
f = Foo()
try:
f.bar
except AttributeError, e:
print 'Par contre', e.message




Un autre problème est que, si je ne me trompe pas, les propriétés de la
métaclasse ne peuvent avoir accès à la classe.
Avatar
Alex Marandon
Alex Marandon wrote:
Bruno Desthuilliers wrote:
Christophe a écrit :
Alex Marandon a écrit :
Bonjour,

Je n'ai pas trouvé dans Python 2.5 de façon de déclarer des
attributs de classe calculés. Ai-je mal cherché ?




Peut-être ce serait possible en créant des simples property dans une
metaclass?



Tiens, j'y avais pas pensé... Par contre - si ça fonctionne, mais bon,
ça devrait, ya pas de raison -, ça implique a priori que ces
propriétés ne se seront accessible que depuis la classe - pas depuis
une instance.




(...)

Un autre problème est que, si je ne me trompe pas, les propriétés de la
métaclasse ne peuvent avoir accès à la classe.



Oups, je n'ai rien dit. Les propriétés de la métaclasses recoivent bien
la classe en paramêtre.
Avatar
Bruno Desthuilliers
Alex Marandon a écrit :
Bruno Desthuilliers wrote:
Alex Marandon a écrit :
Bonjour,

Je n'ai pas trouvé dans Python 2.5 de façon de déclarer des attributs
de classe calculés. Ai-je mal cherché ?



Oui et non, selon ta définition de "attributs de classe calculés".
Pour une définition de "attribut calculé" == property, alors non, tu
n'a pas mal cherché.



Par curiosité, à quelle autre définition penses-tu ?



A un descripteur autre, pourquoi ?-)

J'ai imaginé les implémenter en lecture seule de cette manière:







class classproperty(object):
def __init__(self, func):
self.func = func

def __get__(self, instance, owner):
return self.func(owner)

class Foo(object):
@classproperty
def bar(cls):
return "Je suis un attribut de " + cls.__name__

print Foo.bar


Voyez-vous des problèmes potentiels avec cette implémentation ?



>>> Foo.bar = 42
>>> Foo.bar
42
>>>

Si tu veux éviter ce problème potentiel (à considérer que c'en soit
un...) et être plus 'fidèle' au fonctionnement du type property,
implémente aussi __set__.



J'ai essayé, mais __set__, contrairement à __get__, n'est pas appellé
lorsqu'on accède à l'attribut sur la classe:
<http://docs.python.org/ref/descriptors.html>.




Ah oui, maintenant que tu m'en parles, effectivement... Il me semblait
bien en rédigeant ce post qu'il y avait un loup :-/
Avatar
Bruno Desthuilliers
Alex Marandon a écrit :
Alex Marandon wrote:
Bruno Desthuilliers wrote:
Christophe a écrit :
Alex Marandon a écrit :
Bonjour,

Je n'ai pas trouvé dans Python 2.5 de façon de déclarer des
attributs de classe calculés. Ai-je mal cherché ?




Peut-être ce serait possible en créant des simples property dans une
metaclass?



Tiens, j'y avais pas pensé... Par contre - si ça fonctionne, mais
bon, ça devrait, ya pas de raison -, ça implique a priori que ces
propriétés ne se seront accessible que depuis la classe - pas depuis
une instance.




(...)

Un autre problème est que, si je ne me trompe pas, les propriétés de
la métaclasse ne peuvent avoir accès à la classe.



Oups, je n'ai rien dit. Les propriétés de la métaclasses recoivent bien
la classe en paramêtre.



Forcément, puisque la classe est instance de la métaclasse !-)
Avatar
chris
bonjour,

je debute en python et ce probleme m'interresse
et j'avais voulu faire ceci

>>> class Vide:
... pass
...
>>>
>>> A=Vide()
>>> A.toto='tutu'
>>> A.toto
'tutu'

pourquoi cela ne conviendrait pas ?

A+
chris
Avatar
Alex Marandon
chris wrote:
>>> class Vide:
... pass
...
>>>
>>> A=Vide()
>>> A.toto='tutu'
>>> A.toto
'tutu'

pourquoi cela ne conviendrait pas ?



Dans ton exemple ça convient parfaitement. Mais si A.toto change en
fonction de certaines conditions connues de A, tu peux vouloir faire en
sorte que A.toto sache se mettre à jour tout seul. Par exemple la valeur
de A.toto pourrait venir d'une base de données.
1 2