@符号在Python中做什么?
当前回答
用不同的方式来表达别人的想法:是的,这是一个装饰师。
在Python中,它类似于:
创建函数(在@call下面)调用另一个函数对创建的函数进行操作。这将返回一个新函数。您调用的函数是@的参数。用返回的新函数替换定义的函数。
这可以用于各种有用的事情,因为函数是对象,只是必要的指令。
其他回答
@可以是数学运算符或DECORATOR,但您的意思是DECORATOR。
此代码:
def func(f):
return f
func(lambda :"HelloWorld")()
使用decorator可以写成:
def func(f):
return f
@func
def name():
return "Hello World"
name()
装饰器可以有参数。
你可以看到这个GeeksforGeeks帖子:https://www.geeksforgeeks.org/decorators-in-python/
“at”(@)符号在Python中做什么?
@符号是python提供的利用装饰器的语法糖,套用一个问题,这正是关于decorator在Python中做什么的?
简单地说,decorator允许您修改给定函数的定义,而不触及其最内部(它是闭包)。当你从第三方进口精彩的包装时,这是最常见的情况。你可以想象它,你可以使用它,但你不能触摸它的内心和内心。
这里是一个快速示例,假设我在Ipython上定义了read_a_book函数
In [9]: def read_a_book():
...: return "I am reading the book: "
...:
In [10]: read_a_book()
Out[10]: 'I am reading the book: '
你看,我忘了给它加个名字。如何解决这样的问题?当然,我可以将函数重新定义为:
def read_a_book():
return "I am reading the book: 'Python Cookbook'"
然而,如果不允许我操作原始函数,或者如果有数千个这样的函数需要处理,该怎么办。
通过不同的思维来解决问题,并定义一个新的函数
def add_a_book(func):
def wrapper():
return func() + "Python Cookbook"
return wrapper
然后使用它。
In [14]: read_a_book = add_a_book(read_a_book)
In [15]: read_a_book()
Out[15]: 'I am reading the book: Python Cookbook'
塔达,你看,我修改了read_a_book,但没有触及它的内部封口。没有什么能阻止我配备装修工。
关于什么@
@add_a_book
def read_a_book():
return "I am reading the book: "
In [17]: read_a_book()
Out[17]: 'I am reading the book: Python Cookbook'
@add_a_book是一种新奇而方便的方式来表示read_a_book=add_a_bok(read_a_bok),这是一种语法糖,没有什么比它更令人着迷的了。
“at”(@)符号在Python中做什么?
简而言之,它用于装饰器语法和矩阵乘法。
在decorator的上下文中,此语法:
@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)
and
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
我们可以在这里看到@用于三种上下文:
装饰工因子之间的运算符增广赋值算子
Decorator语法:
在谷歌搜索“decorator python docs”时,最重要的结果之一是“python语言参考”的“复合语句”部分。向下滚动到函数定义部分,我们可以通过搜索单词“decorater”找到该部分,我们看到。。。有很多书要读。但单词“decorator”是词汇表的链接,它告诉我们:
室内装修设计师返回另一个函数的函数,通常使用@wrapper语法作为函数转换应用。常见的装饰器的示例有classmethod()和staticmethod(()。decorator语法只是语法糖,以下两个函数定义在语义上是等价的:定义f(…):...f=静态方法(f)@静态方法定义f(…):...类也存在相同的概念,但在那里不太常用。有关函数定义和类定义,请参阅文档了解有关装饰器的更多信息。
所以,我们看到了
@foo
def bar():
pass
在语义上与:
def bar():
pass
bar = foo(bar)
它们并不完全相同,因为Python使用decorator(@)语法在bar之前计算foo表达式(可以是点查找和函数调用),但在另一种情况下,在bar之后计算foo。
(如果这种差异对代码的含义产生了影响,你应该重新考虑你的生活,因为这是病态的。)
堆叠式装饰器
如果我们回到函数定义语法文档,我们会看到:
@f1(参数)@f2(f2)def func():传递大致相当于def func():传递函数=f1(参数)(f2(函数))
这是一个演示,我们可以首先调用一个装饰器函数,以及堆栈装饰器。在Python中,函数是第一类对象,这意味着您可以将函数作为参数传递给另一个函数,并返回函数。装饰师同时做这两件事。
如果我们堆叠装饰器,那么函数(如定义的那样)首先传递给紧挨着它上面的装饰器,然后传递给下一个,依此类推。
这个about总结了装饰器上下文中@的用法。
操作员@
在语言参考的词法分析部分,我们有一个关于运算符的部分,其中包括@,这使它也是一个运算符:
以下标记是运算符:+ - * ** / // % @<< >> & | ^ ~< > <= >= == !=
在下一页的数据模型中,我们有模拟数字类型一节,
对象__添加__(自己,其他)对象__sub__(自己,其他)对象__多__(自己,其他)对象__matmul__(自己,其他)对象__truediv__(自己,其他)对象__floordiv__(自己,其他)[...]调用这些方法来实现二进制算术运算(+,-,*,@,/,//,[…]
我们看到__matmul__对应于@。如果我们在文档中搜索“matmul”,我们会在标题“PEP465-用于矩阵乘法的专用中缀运算符”下找到Python 3.5新增内容的链接。
它可以通过定义__matmul__()、__rmatmul__()和__imatmul__()用于正则、反射和就地矩阵乘法。
(现在我们了解到@=是就地版本)。它进一步解释了:
矩阵乘法在许多领域中是一种非常常见的运算数学、科学、工程以及@allows的添加编写清洁器代码:S=(H@beta-r).T@inv(H@V@H.T)@(H@beta-r)而不是:S=点((点(H,β)-r).T,dot(inv(dot(点(H,V),H.T)),dot(H,beta)-r))
虽然这个运算符可以重载,几乎可以做任何事情,例如,在numpy中,我们可以使用这个语法来计算数组和矩阵的内积和外积:
>>> from numpy import array, matrix
>>> array([[1,2,3]]).T @ array([[1,2,3]])
array([[1, 2, 3],
[2, 4, 6],
[3, 6, 9]])
>>> array([[1,2,3]]) @ array([[1,2,3]]).T
array([[14]])
>>> matrix([1,2,3]).T @ matrix([1,2,3])
matrix([[1, 2, 3],
[2, 4, 6],
[3, 6, 9]])
>>> matrix([1,2,3]) @ matrix([1,2,3]).T
matrix([[14]])
就地矩阵乘法:@=
在研究先前的用法时,我们了解到还有原地矩阵乘法。如果我们尝试使用它,我们可能会发现它尚未为numpy实现:
>>> m = matrix([1,2,3])
>>> m @= m.T
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: In-place matrix multiplication is not (yet) supported. Use 'a = a @ b' instead of 'a @= b'.
当它实现时,我希望结果如下:
>>> m = matrix([1,2,3])
>>> m @= m.T
>>> m
matrix([[14]])
从Python 3.5开始,“@”用作矩阵乘法的专用中缀符号(PEP 0465——请参见https://www.python.org/dev/peps/pep-0465/)
Python装饰器就像函数或类的包装器。这还是太概念化了。
def function_decorator(func):
def wrapped_func():
# Do something before the function is executed
func()
# Do something after the function has been executed
return wrapped_func
上面的代码是装饰函数的装饰器的定义。function_decorator是装饰器的名称。
wrapped_func是内部函数的名称,实际上它只在这个decorator定义中使用。func是被修饰的函数。在内部函数wrapped_func中,我们可以在调用func之前和之后执行任何操作。在定义了decorator之后,我们只需按如下方式使用它。
@function_decorator
def func():
pass
然后,每当我们调用函数func时,我们在decorator中定义的行为也将被执行。
例子:
from functools import wraps
def mydecorator(f):
@wraps(f)
def wrapped(*args, **kwargs):
print "Before decorated function"
r = f(*args, **kwargs)
print "After decorated function"
return r
return wrapped
@mydecorator
def myfunc(myarg):
print "my function", myarg
return "return value"
r = myfunc('asdf')
print r
输出:
Before decorated function
my function asdf
After decorated function
return value
推荐文章
- Numpy Max vs amax vs maximum
- 我应该在.gitignore文件中添加Django迁移文件吗?
- 每n行有熊猫
- 实例属性attribute_name定义在__init__之外
- 如何获取在Python中捕获的异常的名称?
- 第一次出现的值大于现有值的Numpy
- 如何从Python函数中返回两个值?
- 前一个月的Python日期
- Python中方括号括起来的列表和圆括号括起来的列表有什么区别?
- Python日志记录不输出任何东西
- 每n秒运行特定代码
- SQLAlchemy是否有与Django的get_or_create等价的函数?
- 如何将python datetime转换为字符串,具有可读格式的日期?
- 美丽的汤和提取div及其内容的ID
- 在Python中重置生成器对象