Peu de gens connaissent 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
Quels sont les usages et abus possibles de cette fonctionnalité en Python? Une bonne utilisation à ma connaissance est l'utilisation par PLY de la 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?
python
function
attributes
Eli Bendersky
la source
la source
Réponses:
J'utilise généralement des attributs de fonction comme stockage pour les annotations. Supposons que je veuille écrire, dans le style de C # (indiquant qu'une certaine méthode devrait faire partie de l'interface de service Web)
alors je peux définir
Ensuite, lorsqu'un appel de service Web arrive, je recherche la méthode, vérifie si la fonction sous-jacente a l'attribut is_webmethod (la valeur réelle n'est pas pertinente) et refuse le service si la méthode est absente ou non destinée à être appelée sur le Web.
la source
.__doc__
Je les ai utilisés comme variables statiques pour une fonction. Par exemple, étant donné le code C suivant:
Je peux implémenter la fonction de manière similaire en Python:
Cela tomberait certainement dans la partie "abus" du spectre.
la source
Vous pouvez faire des objets de manière JavaScript ... Cela n'a aucun sens mais cela fonctionne;)
la source
def test()
vraiment nécessaire?Je les utilise avec parcimonie, mais ils peuvent être assez pratiques:
Maintenant, je peux utiliser
log
tout au long de mon module et rediriger la sortie simplement en définissantlog.logfile
. Il existe de nombreuses autres façons d'accomplir cela, mais celui-ci est léger et simple. 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 unelogfile
variable globale .la source
Les attributs de fonction peuvent être utilisés pour écrire des fermetures légères qui enveloppent le code et les données associées ensemble:
1.00934004784
2.00644397736
3.01593494415
la source
time.sleep(1)
est aussi mieux queos.system('sleep 1')
J'ai créé ce décorateur d'aide pour définir facilement les attributs de fonction:
Un cas d'utilisation consiste à créer une collection d'usines et à interroger le type de données qu'elles peuvent créer au niveau méta d'une fonction.
Par exemple (très stupide):
la source
factory1.datatype=list
juste en dessous de la déclaration comme des décorateurs à l'ancienne?items()
place deiteritems()
.Parfois, j'utilise un attribut d'une fonction pour mettre en cache des valeurs déjà calculées. Vous pouvez également avoir un décorateur générique qui généralise cette approche. Soyez conscient des problèmes de concurrence et des effets secondaires de ces fonctions!
la source
J'ai toujours pensé que la seule raison pour laquelle cela était possible était qu'il y avait un endroit logique pour mettre une chaîne de doc ou autre. Je sais que si je l'utilisais pour n'importe quel code de production, cela perturberait la plupart des lecteurs.
la source