Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use @ in python.. and the @property and the @classmethod

Tags:

python

this is my code:

def a():
    print 'sss'

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

b()

and the Traceback is:

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

so how to use the '@'

thanks

updated

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

aa=a()
print aa.b

it print :

sss
None

how to use @property

thanks

updated2

and the classmethod:

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

aa=a()
print aa.b

the it print :

<bound method classobj.b of <class __main__.a at 0x00B2DC00>>
like image 724
zjm1126 Avatar asked Dec 18 '22 01:12

zjm1126


2 Answers

A decorator needs to be a callable object (either a function or an object implementing __call__), where the parameter is the function that has been decorated, and the result is a function that will replace the function that has been decorated, so, to use your example of printing 'sss' instead of printing 'aaa':

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

Or, a more elaborate example:

>>> 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!

Edit
As for your updated question, you need to look at the documentation for @property. It's not clear exactly what you are trying to accomplish, although my guess is that you want:

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

aa=a()
print aa.b # prints 'sss', whereas without @property, prints <function ... >
like image 57
Michael Aaron Safyan Avatar answered Feb 23 '23 01:02

Michael Aaron Safyan


The line @a() means "a is a callable, returning some other callable, which can be called with a function as its only argument and will return a callable". If you're not familiar with the term callable, it's just a generalization of function: it can be a function, a class, or an instance of a class that has a __call__ method.

Your def a is returning None, so you're clearly violating the "decorator contract" that you're requesting with the @a() syntax.

If you just used @a, without the (), then a would have to accept the function as its argument and return a callable.

I'm not sure what you're trying to accomplish, but if it's just "print something in a decorator for a function, then this would work:

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

Now you can use @a() and live happily ever after, since this version does respect the "decorator contract" I explained in the first paragraph.

like image 24
Alex Martelli Avatar answered Feb 23 '23 01:02

Alex Martelli