187 votes

Attributs de la fonction Python - utilisations et abus

Peu sont au courant de cette fonctionnalité, mais les fonctions (et méthodes) de Python peuvent avoir des attributs . Voir:

 >>> def foo(x):
...     pass
...     
>>> foo.score = 10
>>> dir(foo)
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name', 'score']
>>> foo.score
10
>>> foo.score += 1
>>> foo.score
11
 

Quelles sont les utilisations et les abus possibles de cette fonctionnalité en Python? À mon avis, PLY utilise le docstring pour associer une règle de syntaxe à une méthode. Mais qu'en est-il des attributs personnalisés? Y a-t-il de bonnes raisons de les utiliser?

146voto

Martin v. Löwis Points 61768

Je l'utilise généralement les attributs des fonctions comme le stockage des annotations. Supposons que je veux écrire, dans le style de C# (indiquant qu'une certaine méthode devrait être une partie de l'interface du service web)

class Foo(WebService):
    @webmethod
    def bar(self, arg1, arg2):
         ...

ensuite, je peux définir

def webmethod(func):
    func.is_webmethod = True
    return func

Alors, quand un webservice appel arrive, je recherche la méthode, vérifiez si la fonction sous-jacente a la is_webmethod attribut (la valeur réelle est sans importance), et de refuser le service, si la méthode est absent ou ne doit pas être appelée sur le web.

121voto

mipadi Points 135410

Je les ai utilisés comme variables statiques pour une fonction. Par exemple, donnez le code C suivant:

 int fn(int i)
{
    static f = 1;
    f += i;
    return f;
}
 

Je peux implémenter la fonction de manière similaire en Python:

 def fn(i):
    fn.f += i
    return fn.f
fn.f = 1
 

52voto

defnull Points 1489

Vous pouvez faire des objets de la manière JavaScript ... Cela n'a aucun sens mais ça marche;)

 >>> def FakeObject():
...   def test():
...     print "foo"
...   FakeObject.test = test
...   return FakeObject
>>> x = FakeObject()
>>> x.test()
foo
 

45voto

user140352 Points 409

Découvrez PEP 232 .

15voto

Robert Rossney Points 43767

Je les utilise avec parcimonie, mais ils peuvent être très pratiques:

 def log(msg):
   log.logfile.write(msg)
 

Maintenant, je peux utiliser log tout au long de mon module et rediriger la sortie simplement en définissant log.logfile . Il y a beaucoup d'autres façons d'accomplir cela, mais c'est simple et léger. Et même si ça sentait drôle la première fois que je l'ai fait, j'ai fini par croire que ça sent mieux que d'avoir une variable logfile globale.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X