use*_*484 5 python attributes class decorator python-decorators
我试图在这里找到答案,但不能.
@obj.func # works
@obj.func(**kwargs) #works
@obj.func1(**kwargs).func2 #-> syntax error
Run Code Online (Sandbox Code Playgroud)
我不明白为什么第三种形式是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
Run Code Online (Sandbox Code Playgroud)
你可以使用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
Run Code Online (Sandbox Code Playgroud)
但为什么禁止遵循"捷径语法":
@redcross.copy(color="blue").caller
def plot_data2(**kwargs):
pass
Run Code Online (Sandbox Code Playgroud)
但我能做到:
@redcross.copy_and_decorate(color="blue")
def plot_data2(**kwargs):
pass
Run Code Online (Sandbox Code Playgroud)
第一种形式看起来更好,至少我更了解背后的意图.
该函数定义语法不允许进一步带点名称电话; 语法仅限于带点名称和一个可选的通话末:
decorated ::= decorators (classdef | funcdef)
decorators ::= decorator+
decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE
funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite
dotted_name ::= identifier ("." identifier)*
Run Code Online (Sandbox Code Playgroud)
请注意,这不是一个完整的表达式,而是一个非常有限的子集.
这与PEP相呼应,其中指出:
装饰器语句受限于它可以接受的内容 - 任意表达式都不起作用.Guido更喜欢这种,因为有一种直觉[17].
和
使用返回装饰器的函数的基本原理是@符号后面的部分可以被认为是一个表达式(虽然在语法上仅限于一个函数),并且调用该表达式返回的任何内容.参见声明参数[16].
强调我的.
因此,虽然将来很容易将语法更改为@test,但我还是要坚持使用更受限制的形式,除非提供真正的用例,允许@test提高可读性.(@foo().bar()不算数,因为我不指望你曾经需要那个).
您必须说服Guido和其他核心开发人员,您的案例是一个值得解除这些限制的正确用例!
| 归档时间: |
|
| 查看次数: |
493 次 |
| 最近记录: |