python中 @ 的含义与用法

目录

一、表示修饰符/装饰器。

调用被修饰函数时,自动执行添加的功能代码

@property

二、表示矩阵乘法。


一、表示修饰符/装饰器。

        可以在模块或者类的定义层内对函数进行修饰。出现在函数定义的前一行,不允许和函数定义在同一行。

        一个@修饰符就是一个函数【格式:@修饰名,它将被修饰的函数作为参数,并返回修饰后的同名函数或其他可调用的东西(如果返回不是一个可调用的对象那么会报错)。可在代码运行期间动态增加功能。本质上,decorator 就是一个返回函数的高阶函数

        会直接执行函数。即可等价替换为: 修饰名(被修饰函数())

例1:

def funA(desA):
 print("It's funA")
 
def funB(desB):
 print("It's funB")
 
@funA
def funC():
 print("It's funC")
运行结果:
It's funA

例2:

可以看出,该例子中@test等价于 test(xxx()),但是这种写法你得考虑python代码的执行顺序。

def test(func):
    print("a")
    return func()
    
@test
def xxx():
    print('Hello world!')
运行结果:
a
Hello world!

例3:

为更深刻理解该用法,来个复杂点的嵌套型。

def funA(desA):
 print("It's funA")
 
 print('---')
 print(desA)
 desA()
 print('---')
 
def funB(desB):
 print("It's funB")
 
@funB
@funA
def funC():
 print("It's funC")
运行结果:
It's funA
---
<function funC at 0x00000252D2545550>
It's funC
---
It's funB

解析:

  1.  @funB 修饰装饰器@funA,@funA 修饰函数定义def funC(),将funC()作为funA()的参数,再将funA(funC())作为funB()的参数。 执行的时候自下而上,先执行funA(funC()),再执行funB(funA(funC()))。注意,funC()并不执行,除非funA()函数中给出了执行funA()的代码。
  2. 打印desA,其传的是funC()的地址,即desA现在为函数desA()。 执行desA()即执行funC(),desA=desA()=funC()

调用被修饰函数时,自动执行添加的功能代码

这块内容参考自:装饰器 - 廖雪峰的官方网站

def now():
    print('2015-3-25')


def log(func):
    print('Jason')
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

@log
def now():
    print('2015-3-25')

执行上面后输出如下:

Jason

调用now()函数时,不仅会运行now()函数本身,还会在运行now()函数前打印一行日志:

>>> now()

call now():
2015-3-25

由于log()是一个decorator,返回一个函数,所以,原来的now()函数仍然存在,只是现在同名的now变量指向了新的函数,于是调用now()将执行新函数,即在log()函数中返回的wrapper()函数

wrapper()函数的参数定义是(*args, **kw),因此,wrapper()函数可以接受任意参数的调用。在wrapper()函数内,首先打印日志,再紧接着调用原始函数。

如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,写出来会更复杂。比如,要自定义log的文本:

def now():
    print('2015-3-25')


def log(text):
    print('Jason')
    def decorator(func):
        print('Cool')
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator


@log('execute')
def now():
    print('2015-3-25')

执行上面后输出如下:

Jason
Cool

调用now()函数时:

>>> now()

execute now():
2015-3-25

我们来剖析上面的语句,首先执行log('execute'),返回的是decorator函数,再调用返回的函数,参数是now函数,返回值最终是wrapper函数


@property

Python内置的@property就是很常用的一个装饰器,负责把一个方法变成属性调用。

class DataSet(object):
    def __init__(self):
        self._images = 1
        self._labels = 2 #定义属性的名称
        
    @property
    def images(self): #方法加入@property后,这个方法相当于一个属性,这个属性可以让用户进行使用,而且用户有没办法随意修改。
        return self._images 
        
    @property
    def labels(self):
        return self._labels


l = DataSet()
#用户进行属性调用的时候,直接调用images即可,而不用知道属性名_images,因此用户无法更改属性,从而保护了类的属性。

print(l.images) # 加了@property后,可以用调用属性的形式来调用方法,后面不需要加()。

二、表示矩阵乘法。

        不常用。是torch.matmul()的重写

例:

import torch

n=100
x = torch.ones(n,2)
x[:,0].uniform_(-1.,1)  # 第一列变换至(-1.,1) 之间
print(x[:5])  # 输出前5行
a = torch.tensor([3.,2.]) # 一维Tensor
print(a)
print(a.shape)
y = x@a
print(y)
print(y.shape)
输出结果:
tensor([[ 0.8230,  1.0000],
        [ 0.2427,  1.0000],
        [-0.7416,  1.0000],
        [-0.1267,  1.0000],
        [ 0.7767,  1.0000]])
tensor([3., 2.])
torch.Size([2])
tensor([ 4.4691,  2.7281, -0.2249,  1.6198,  4.3302,  3.3386,  1.9908, -0.8602,
         4.9401,  1.9773,  4.5304, -0.1322,  3.9059, -0.6714,  1.8961,  3.7886,
         0.8241,  4.4958,  2.2765,  2.0459,  3.6542,  3.0824,  2.8941,  1.0526,
         4.8735,  1.4954,  3.0208,  4.0778,  2.3491,  2.2261,  3.1072,  1.0640,
         1.7861, -0.8534,  3.2532,  1.5553,  0.2124,  3.6449,  1.6078, -0.1138,
         4.2842,  3.7184,  2.2547,  3.4069,  3.6274,  0.4879,  1.4638,  3.9289,
         3.3475,  4.1895,  1.5572,  0.8312,  2.9297, -0.9266,  0.4067,  2.5237,
         0.6808,  4.9553,  3.3838,  0.5514,  4.8429,  0.0513,  3.4206,  0.3634,
         4.7817,  3.0385,  2.3276, -0.0794,  3.4981,  4.3776, -0.8681, -0.4573,
         3.6906,  1.2463,  1.4817,  4.0007,  4.7871,  2.5638,  4.2755,  3.1731,
         3.4726,  2.1015, -0.8896,  1.4156,  1.2603,  4.0047,  3.3631,  3.5998,
         3.2414, -0.1534,  3.6266,  0.3750,  4.4118, -0.0199,  1.6172,  3.2992,
        -0.2325,  1.8240,  0.5580,  2.1420])
torch.Size([100])

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值