2010-04-28 35 views
4

voici mon code:comment utiliser @ en python .. et le @property et le @classmethod

def a(): 
    print 'sss' 

@a() 
def b(): 
    print 'aaa' 

b() 

et le retraçage est:

sss 
Traceback (most recent call last): 
    File "D:\zjm_code\a.py", line 8, in <module> 
    @a() 
TypeError: 'NoneType' object is not callable 

donc comment utiliser le « @ '

grâce

mis à jour

class a: 
    @property 
    def b(x): 
     print 'sss' 

aa=a() 
print aa.b 

il print:

sss 
None 

comment utiliser @property

grâce

updated2

et classmethod:

class a: 
    @classmethod 
    def b(x): 
     print 'sss' 

aa=a() 
print aa.b 

l'on print:

<bound method classobj.b of <class __main__.a at 0x00B2DC00>> 

Répondre

9

Un décorateur doit être un objet appelable (soit une fonction ou un objet __call__ mise en œuvre), où le paramètre est la fonction qui a été décoré, et le résultat est fonction qui remplacera la fonction qui a été décoré, donc, d'utiliser votre exemple d'impression « sss » au lieu d'imprimer « aaa »:

 
>>> def a(f): 
...  def replacementfunc(): 
...   print 'sss' 
...  return replacementfunc; 
... 
>>> @a 
... def b(): 
...  print 'aaa' 
... 
>>> b() 
sss 

Ou, un exemple plus complexe:

 
>>> class print_decorator(object): 
...  def __init__(self,text): 
...  self.text = text; 
...  def __call__(self,f): 
...  def replacement(): 
...   print self.text; 
...  return replacement; 
... 
>>> @print_decorator("Hello world!") 
... def b(): 
...  print 'aaa'; 
... 
>>> b() 
Hello world! 

Modifier
Quant à votre question mise à jour, vous devez consulter la documentation pour @property. On ne sait pas exactement ce que vous essayez d'accomplir, même si je suppose que vous voulez:

 
class a: 
    @property 
    def b(self): 
     return 'sss' 

aa=a() 
print aa.b # prints 'sss', whereas without @property, prints <function ... > 
+0

Je peux me tromper dans ce contexte ... mais c'est ce que je pense ... un décorateur ne devrait pas remplacer la fonction totalement .. il devrait être la décoration .. i. e dire *** aaa *** (*** à l'avant et est imprimé à l'aide d'un décorateur arrière) – SysAdmin

+0

salut Michael, regardez le – zjm1126

+1

mis à jour @SysAdmin, un décorateur peut faire en retournant une fonction qui appelle la fonction qui a été transmis; cependant, la sémantique réelle est que la fonction retournée prend le nom de la fonction. L'utilisation de @x def f(): .... est la même chose que def f(): ... suivi de f = x (f); –

4

La ligne @a() signifie «a est un appelable, le retour d'une autre appelable, ce qui peut être appelé avec une fonction comme seul argument et retournera un appelable ". Si vous n'êtes pas familier avec le terme callable, il s'agit simplement d'une généralisation de function: il peut s'agir d'une fonction, d'une classe ou d'une instance d'une classe ayant une méthode __call__.

Votre def a renvoie None, donc vous enfreignez clairement le "contrat décorateur" que vous demandez avec la syntaxe @a().

Si vous venez d'utiliser @a, sans (), alors a devraient accepter la fonction comme argument et renvoie un appelable.

Je ne suis pas sûr de ce que vous essayez d'accomplir, mais si elle est juste « imprimer quelque chose dans un décorateur pour une fonction, cela pourrait fonctionner:

def a(): 
    print 'sss' 
    return lambda f: f 

maintenant vous pouvez utiliser @a() et je vis heureux pour toujours, puisque cette version respecte le "contrat décorateur" que j'ai expliqué au premier paragraphe

+0

salut alex, regardez la – zjm1126

+1

mise à jour @zjm, être sensible: une question par question! Quoi qu'il en soit, la propriété retourne ce que le 'def b()' retourne, et qui est 'none' puisque vous tombez juste à côté de la fin, et _de course_ l'impression du classmethod (sans appeler) vous montre qu'il est une méthode liée à la classe, * * quoi d'autre ** pourrait-il être montrer ?! –