如何在python中使用@以及@property和@classmethod

时间:2010-04-28 01:50:58

标签: python

这是我的代码:

def a():
    print 'sss'

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

b()

和Traceback是:

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

所以如何使用'@'

感谢

更新

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

aa=a()
print aa.b

打印:

sss
None

如何使用@property

感谢

updated2

和classmethod:

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

aa=a()
print aa.b

它打印:

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

2 个答案:

答案 0 :(得分:9)

装饰器需要是一个可调用对象(实现__call__的函数或对象),其中参数是已装饰的函数,结果是一个函数,它将替换已装饰的函数,所以,使用打印'sss'而不是打印'aaa'的例子:

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

或者,更详细的例子:

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

修改
至于您的更新问题,您需要查看@property的文档。目前尚不清楚你想要完成什么,虽然我的猜测是你想要的:

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

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

答案 1 :(得分:4)

@a()表示“a是可调用的,返回一些其他可调用的,可以使用函数作为其唯一参数调用,并返回可调用的”。如果您不熟悉术语callable,它只是function的概括:它可以是具有__call__方法的类的函数,类或实例

您的def a正在返回None,因此您明显违反了使用@a()语法请求的“装饰者合同”。

如果您刚使用@a,而没有(),那么a必须接受该函数作为其参数并返回一个可调用的。

我不确定你要完成什么,但如果它只是“在装饰器中打印某个功能的东西,那么这将起作用:

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

现在你可以使用@a()并过上幸福的生活,因为这个版本确实尊重我在第一段中解释的“装饰合同”。 / p>