这里的目标是将全局函数称为装饰器。
#coding: utf-8
def Test(method_to_decorate):
print 'Decorator'
def wrapper(self):
return method_to_decorate(self)
return wrapper
class Smth(object):
def Test(self):
print 'NOT a decorator!'
a=globals()['Test']
#@globals()['Test'] --> SyntaxError
@a # works fine
def Fun(self):
print "Smth.Fun()"
l = Smth()
l.Fun()
在@globals()['Test']
给出SyntaxError
时,使用未注释的方法可以正常工作。 为什么?我非常确定Test
中 globals()
存在。
@
之后的事物必须是一个接受另一个函数作为其参数之一的函数,我是对的吗? globals()['Test']
就是这样一个功能,不是吗?然后,在我看来,@globals()['Test']
必须是正确的(逻辑上正确)。
修改
这可以按预期工作:
def Ex(*args):
print 'Ex({})'.format(args)
globals()['Ex']('hello') # just calling a function
使用装饰器时,会调用一个函数。我们可以像上面那样调用函数,但是不能像这样使用装饰器。 也许这是某种Python错误或逻辑错误组织?
答案 0 :(得分:6)
这是一个SyntaxError,因为Python的语法明确不允许这样做; @
右侧的标记不是表达式。 1相反,有效的语法是:
decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
(括在方括号([ ]
)中的短语表示零次或一次出现(换句话说,随附的短语是可选的)。)2
根据上述内容,您可以通过将globals()['Test']
转换为虚线名称来实现此目的。以下示例应该有效:
g = globals()
@g.get('Test')
def Fun(self):
pass
x = globals()['Test']
@x
def Fun(self):
pass
或者,正如您所注意到的,您可以跳过语法糖并手动装饰,这可能是最不好的选择。
答案 1 :(得分:0)
因为Python解析器不是为了将索引访问识别为装饰器语法的一部分而设计的。考虑编写一个单独的函数来代替访问globals()
。