gpt4 book ai didi

Python 装饰器 @func().attribute 语法错误

转载 作者:行者123 更新时间:2023-12-04 18:37:19 26 4
gpt4 key购买 nike

我试图在这里找到答案,但找不到。

@obj.func # works
@obj.func(**kwargs) #works
@obj.func1(**kwargs).func2 #-> syntax error

我不明白为什么第三种形式是 SyntaxError,对我来说似乎没有违反任何 python 语法,我很清楚用户想要做什么(见下面的例子)。

我看了 pep 0318装饰器实现,但没有找到任何答案。

下面是一个使用示例:
class ItemFunc(object):
def __init__(self, fcall=None, **kwargs):
self.defaults = kwargs
self.fcall = None

def __call__(self, *args, **kwargs):
kwargs = dict(self.defaults, **kwargs)
# do something more complex with kwargs
output = self.fcall(*args, **kwargs)
# do something more with output
return output

def caller(self, fcall):
""" set call and return self """
self.call = fcall # after some check obviously
return self

def copy(self,**kwargs):
kwargs = dict(self.defaults, **kwargs)
return self.__class__(self.fcall, **kwargs)

def copy_and_decorate(self, **kwargs):
return self.copy(**kwargs).caller

比你可以使用 ItemFunc 作为装饰器:
@ItemFunc
def plot(**kwargs):
pass

redcross = plot.copy(color="red", marker="+")
@redcross.caller
def plot_data1(**kwargs):
pass

bluecross = redcross.copy(color="blue")
@bluecross.caller
def plot_data2(**kwargs):
pass

但是为什么禁止以下“快捷语法”:
@redcross.copy(color="blue").caller
def plot_data2(**kwargs):
pass

但我可以这样做:
@redcross.copy_and_decorate(color="blue")
def plot_data2(**kwargs):
pass

第一种形式看起来更好,至少我更了解背后的意图。

最佳答案

Function definitions grammar不允许使用更多带点名的电话;语法仅限于带点名称和最后的可选调用:

decorated      ::=  decorators (classdef | funcdef)
decorators ::= decorator+
decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE
funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite
dotted_name ::= identifier ("." identifier)*

请注意,这不是一个完整的表达式,而是一个非常有限的子集。

这与 PEP 相呼应,其中指出:

The decorator statement is limited in what it can accept -- arbitrary expressions will not work. Guido preferred this because of a gut feeling [17] .





The rationale for having a function that returns a decorator is that the part after the @ sign can be considered to be an expression (though syntactically restricted to just a function), and whatever that expression returns is called. See declaration arguments [16] .



强调我的。

理由是 Guido feels there isn't a real use case for allowing more :

So while it would be quite easy to change the syntax to @test in the future, I'd like to stick with the more restricted form unless a real use case is presented where allowing @test would increase readability. (@foo().bar() doesn't count because I don't expect you'll ever need that).



您必须说服 Guido 和其他核心开发人员您的案例是一个值得取消这些限制的正确用例!

关于Python 装饰器 @func().attribute 语法错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32567563/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com