Python中的注解“@”

Python3.0之后加入新特性Decorators,以@为标记修饰function和class。有点类似c++的宏和java的注解。Decorators用以修饰约束function和class,分为带参数和不带参数,影响原有输出,例如类静态函数我们要表达的时候需要函数前面加上修饰@staticmethod或@classmethod,为什么这样做呢?下面用简单的例子来看一下,具体内容可以查看:官方解释

不带参数的单一使用

def spamrun(fn):
    def sayspam(*args):
        print("spam,spam,spam")
        fn(*args)
    return sayspam
@spamrun
def useful(a,b):
    print(a*b)

if __name__ == "__main__"
  useful(2,5) 

运行结果

spam,spam,spam
10

函数useful本身应该只是打印10,可是为什么最后的结果是这样的呢,其实我们可以简单的把这个代码理解为

def spamrun(fn):
    def sayspam(*args):
        print("spam,spam,spam")
        fn(*args)
    return sayspam

def useful(a,b):
    print(a*b)

if __name__ == "__main__"
  useful = spamrun(useful)
  useful(a,b)

不带参数的多次使用

def spamrun(fn):
    def sayspam(*args):
        print("spam,spam,spam")
        fn(*args)
    return sayspam


def spamrun1(fn):
    def sayspam1(*args):
        print("spam1,spam1,spam1")
        fn(*args)
    return sayspam1

@spamrun
@spamrun1
def useful(a,b):
    print(a*b)

if __name__ == "__main__"
  useful(2,5) 

运行结果

spam,spam,spam
spam1,spam1,spam1
10

这个代码理解为

if __name__ == "__main__"
  useful = spamrun1(spamrun(useful))
  useful(a,b)

带参数的单次使用

def attrs(**kwds):
    def decorate(f):
        for k in kwds:
            setattr(f, k, kwds[k])
        return f

    return decorate


@attrs(versionadded="2.2",
       author="Guido van Rossum")
def mymethod(f):
    print(getattr(mymethod,'versionadded',0))
    print(getattr(mymethod,'author',0))
    print(f)

if __name__ == "__main__"
mymethod(2)   

运行结果

2.2
Guido van Rossum
2

这个代码理解为

if __name__ == "__main__"
  mymethod = attrs(versionadded="2.2",
          author="Guido van Rossum).(mymethod)
  mymethod(2)

带参数的多次使用
这次我们来看一个比较实际的例子,检查我们函数的输入输出是否符合我们的标准,比如我们希望的输入是(int,(int,float))输出是(int,float),这个例子在官网里有,但是在3.6版本中使用有些问题,这里进行了一些改动,如果要进一步了解可以看下functionTool。

def accepts(*types):
    def check_accepts(f):
        def new_f(*args, **kwds):
            assert len(types) == (len(args) + len(kwds)), \
                "args cnt %d does not match %d" % (len(args) + len(kwds), len(types))
            for (a, t) in zip(args, types):
                assert isinstance(a, t), \
                    "arg %r does not match %s" % (a, t)
            return f(*args, **kwds)

        update_wrapper(new_f, f)
        return new_f

    return check_accepts


def returns(rtype):
    def check_returns(f):
        def new_f(*args, **kwds):
            result = f(*args, **kwds)
            assert isinstance(result, rtype), \
                "return value %r does not match %s" % (result, rtype)
            return result

        update_wrapper(new_f, f)
        return new_f

    return check_returns


@accepts(int, (int, float))
@returns((int, float))
def func(arg1, arg2):
    return arg1 * arg2    

if __name__ == "__main__"
  a = func(1, 'b')
  print(a)    

这里故意输入了错误的参数,所以运行结果将我们的断言打印了出来

AssertionError: arg 'b' does not match (<class 'int'>, <class 'float'>)

这个代码理解为

if __name__ == "__main__"
  func = accepts(int, (int, float)).(accepts((int, float)).(mymethod))
  a = func(1, 'b')
  print(a)

说到这里,大家不难看出其实我们可以使用Decorators做很多工作,简化代码,使逻辑更清晰等。还有更多的用法等着大家自己去挖掘了,这里只简单的介绍了针对函数的用法,其实还可以针对class使用,具体的大家自己看看官方介绍,结合这篇文档应该就不难理解了。

原文地址:Python中的注解“@”

### 回答1: 这个错误是由于两个数组的形状不兼容导致的。其一个数组的形状是(none, 1),另一个数组的形状是(none, 2)。这意味着它们的行数相同,但列数不同。在某些情况下,这可能是由于数据类型不匹配或数据维度不正确引起的。您需要检查数据并确保它们具有相同的形状和数据类型。如果需要,您可以使用numpy库的reshape函数来更改数组的形状。 ### 回答2: ValueError: shapes (None, 1) and (None, 2) are incompatible。是Python语言常见的错误,通常出现在人工智能、机器学习等领域。这个错误提示显示的是两个数组的形状(Shapes)不兼容。简单来说,就是指两个数组的维度不一致,无法进行运算。 其,None代表的是数组的尺寸,意味着这个维度大小可以被任意赋值,但是两个数组在某些维度上的大小是不匹配的。这个问题通常可以通过改变数组形状或对数组进行重新组合来解决。 实际上,这个错误可能涉及到函数、方法、操作、层、参数等各种因素。其,常见的原因是两个数组的一部分维度大小不匹配、缺少数据或维度没有进行扩展等。在解决这个错误的过程,需要认真检查代码涉及到的所有参数和变量,特别是需要仔细检查数组的形状、大小和数据类型是否匹配。 在数据科学领域,这个错误通常会出现在机器学习的模型训练和预测过程。如果两个数组的维度不匹配,可能会导致无法正常训练模型或预测出错。因此,在使用Python进行数据处理和机器学习的过程,需要注意数组的形状和大小,以避免这个错误的出现。 总之,ValueError: shapes (None, 1) and (None, 2) are incompatible。这个错误提示意味着两个数组的形状不兼容,需要进行调整和匹配才能进行运算。在处理数据和编写代码时需要认真检查数据的大小、形状和类型,以避免这个错误的出现。 ### 回答3: 这个错误是由于两个numpy数组的形状不兼容而导致的。在 numpy ,数组的形状是非常重要的,不同的形状可以产生不同的结果,如果两个数组的形状不兼容,就会出现这种 ValueError。 首先我们需要了解一下 numpy 数组的形状。在 numpy ,数组的形状通常由两个属性组成:维度和大小。维度表示数组的维度数量,大小表示每个维度上的元素数量。比如一个二维数组的形状可以表示为 (3, 4),其 3 表示该数组有 3 个维度,4 表示每个维度上有 4 个元素。 在出现 "shapes (none, 1) and (none, 2) are incompatible" 的错误时,通常是因为两个数组的形状在维度数量或者每个维度上的元素数量上不匹配。其, (none, 1) 表示第一个数组的形状为一维数组,大小为 none 表示元素数量未知,后面的 1 表示每个维度上有 1 个元素。同理,(none, 2) 表示第二个数组的形状为一维数组,大小为 none 表示元素数量未知,后面的 2 表示每个维度上有 2 个元素。 针对这种错误,我们需要检查一下代码两个数组的形状是否一致。如果不一致,我们需要进行相应的修改,使它们的形状兼容。具体的做法可以通过 numpy 提供的一些数组操作函数来实现,比如 reshape()函数可以改变数组的形状, concatenate()函数可以将两个数组拼接在一起,等等。 在解决这个错误时,我们还需要注意一些细节,比如 numpy 不同操作函数对数组形状的要求可能会有所不同,我们需要根据具体情况进行选择。此外,我们还需要注意避免在操作数组时出现类型不一致的错误,比如将字符串类型的数组和浮点类型的数组进行拼接,这也可能会导致 ValueError 错误的出现。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值