Python中的“@”(@)符号有什么作⽤?
我正在看⼀些使⽤@符号的Python代码,但我不知道它的作⽤。 我也不知道要搜索什么,因为搜索Python⽂档时会出现,或者当包含@符号时Google不会返回相关结果。
#1楼
此代码段:
def decorator(func):
return func
@decorator
def some_func():
pass
等效于以下代码:
def decorator(func):
return func
def some_func():
pass
some_func = decorator(some_func)
在装饰器的定义中,您可以添加⼀些通常不会由函数返回的修改内容。
#2楼
前⾔
我承认,花了我很多时间才能完全理解这个概念,所以我将分享我所学到的为他⼈省下⿇烦的知识。
名称装饰器 (我们在函数定义之前使⽤@语法定义的东西)可能是此处的罪魁祸⾸。
例
class Pizza(object):
def __init__(self):
def __call__(self, topping):
# When using '@instance_of_pizza' before a function definition
# the function gets passed onto 'topping'.
def __repr__(self):
return ppings)
pizza = Pizza()
@pizza
def cheese():
return 'cheese'
@pizza
def sauce():
return 'sauce'
print pizza
# ['cheese', 'sauce']
这表明在修饰符之后定义的function / method / class基本上只是在@符号之后作为argument传递给function / method 。第⼀次发现
微框架Flask从⼀开始就以以下格式引⼊装饰器 :
from flask import Flask
app = Flask(__name__)
@ute("/")
def hello():
return "Hello World!"
依次将其翻译为:
rule = "/"
view_func = hello
# They go as arguments here in 'flask/app.py'
def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
pass
意识到这⼀点终于使我与Flask和平相处。
#3楼
⽤不同的⽅式来说其他⼈:是的,它是⼀个装饰器。
在Python中,就像:
1. 创建⼀个函数(在@调⽤之后)python新手代码及作用
2. 调⽤另⼀个函数以对您创建的函数进⾏操作。 这将返回⼀个新函数。 您调⽤的函数是@的参数。
3. ⽤返回的新函数替换定义的函数。
这可以⽤于各种有⽤的东西,因为功能是对象,⽽只是指令⽽已,因此成为可能。
#4楼
在Python 3.5中,您可以将@重载为运算符。 它被命名为__matmul__ ,因为它旨在进⾏矩阵乘法,但是它可以是您想要的任何东西。 有关详细信息,请参见 。
这是矩阵乘法的简单实现。
class Mat(list):
def __matmul__(self, B):
A = self
return Mat([[sum(A[i][k]*B[k][j] for k in range(len(B)))
for j in range(len(B[0])) ] for i in range(len(A))])
A = Mat([[1,3],[7,5]])
B = Mat([[6,8],[4,2]])
print(A @ B)
此代码产⽣:
[[18, 14], [62, 66]]
#5楼
#6楼
Python中的“ @”(@)符号有什么作⽤?
简⽽⾔之,它⽤于装饰器语法和矩阵乘法。
在装饰器的上下⽂中,此语法为:
@decorator
def decorated_function():
"""this function is decorated"""
等效于此:
def decorated_function():
"""this function is decorated"""
decorated_function = decorator(decorated_function)
在矩阵乘法的上下⽂中, a @ b调⽤a.__matmul__(b) -使⽤以下语法:
a @ b
相当于
dot(a, b)
和
相当于
a = dot(a, b)
其中dot是例如numpy矩阵乘法函数,⽽a和b是矩阵。
您如何独⾃发现呢?
我也不知道要搜索什么,因为搜索Python⽂档时会出现,或者当包含@符号时Google不会返回相关结果。
如果您想对某个特定的python语法有⼀个完整的了解,请直接查看语法⽂件。 对于Python 3分⽀:
~$ grep -C 1 "@" cpython/Grammar/Grammar
decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
decorators: decorator+
--
testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' |
'<<=' | '>>=' | '**=' | '//=')
--
arith_expr: term (('+'|'-') term)*
term: factor (('*'|'@'|'/'|'%'|'//') factor)*
factor: ('+'|'-'|'~') factor | power
我们可以在这⾥看到@在三种情况下使⽤:
装饰⼯
因⼦之间的运算符
扩充的赋值运算符
装饰语法:
在Google上搜索“ decorator python docs”时,将“ Python语⾔参考”的“复合语句”部分作为最⾼结果之⼀。 向下滚动⾄ ,我们可以通过搜索“ decorator”⼀词到该 ,我们发现……有很多东西可供阅读。 但是这个词 ,它告诉我们:
装饰⼯
返回另⼀个函数的函数,通常使⽤@wrapper语法作为函数转换应⽤。 装饰器的常见⽰例是classmethod()和staticmethod() 。
装饰器语法只是语法糖,以下两个函数定义在语义上是等效的:
def f(...): ... f = staticmethod(f) @staticmethod def f(...): ...
类存在相同的概念,但在该类中较少使⽤。 有关装饰器的更多信息,请参见函数定义和类定义的⽂档。
所以,我们看到
def bar():
pass
在语义上与:
def bar():
pass
bar = foo(bar)
它们并不完全相同,因为Python使⽤装饰器( @ )语法在bar之前评估foo表达式(可能是点分查和函数调⽤),但在另⼀种情况下,则在 bar 之后评估foo表达式。
(如果这种差异使代码的含义有所不同,则应重新考虑⾃⼰的⽣活,因为那会是病态的。)
堆叠式装饰器
如果回到函数定义语法⽂档,则会看到:
@f1(arg) @f2 def func(): pass
⼤致相当于
def func(): pass func = f1(arg)(f2(func))
这是⼀个演⽰,我们可以调⽤⾸先是装饰器的函数以及堆栈装饰器。 在Python中,函数是⼀流的对象-这意味着您可以将⼀个函数作为参数传递给另⼀个函数,然后返回函数。 装饰者可以做这两种事情。
如果我们堆叠装饰器,则已定义的函数会⾸先传递到紧接其上的装饰器,然后传递给下⼀个,依此类推。
关于装饰器上下⽂中@的⽤法的总结。
运营商, @
在语⾔参考的词法分析部分,我们有⼀个的 ,其中包括@ ,这使其同时也是⼀个运算符:
以下标记是运算符:
+ - * ** / // % @ << >> & | ^ ~ < > <= >= == !=
在下⼀页的数据模型中,我们有⼀节,
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论