【python注解】自定义注解与动态获取方法注解信息-基础

python的注解是通过装饰器模式实现的,@注解本质是一个函数

def my_annotation(**kwds):
    def decorate(fn):
        for item in kwds.items():
            print(item)
        return fn
    return decorate

@my_annotation(value="this is a annotation", author="Jack")
def test_annotation():
    print("test...")


if __name__ == "__main__":
    annos = test_annotation.__annotations__
    print(annos)

打印结果:

('value', 'this is a annotation')
('author', 'Jack')
{}

上述结果可以理解为将注解信息 { value="this is a annotation", author="Jack" } 作为参数传到my_annotation函数中,将test_annotation函数作为参数传到装饰器函数decorate中

注意decorate这里返回的是fn函数本身,因为你返回什么,加了注解的test_annotation就会变成什么,返回str,则test_annotation将不再是函数,而是str,因此test_annotation.__annotations__会报错不存在该属性,所以要返回fn本身,保持函数类型不变

打印信息最后test_annotation的注解为空字典 {},说明直接在方法上加@注解,其信息不会注入进去,因此需要手动set

def my_annotation(**kwds):
    def decorate(fn):
        for item in kwds.items():
            #print(item)
            key = item[0]
            value = item[1]
            fn.__annotations__[key] = value
        return fn
    return decorate

@my_annotation(value="this is a annotation", author="Jack")
def test_annotation():
    print("test...")


if __name__ == "__main__":
    annos = test_annotation.__annotations__
    print(annos)

打印结果:

{'value': 'this is a annotation', 'author': 'Jack'}

这样注解信息就被注入到方法中了。由于__annotations__本质是一个字典,因此可以采用字典的那套方法去判断、获取方法上的注解信息

一般写一个基于反射的python框架中很可能会需要动态获取注解信息,下面给出一个简单获取案例

def codeC():
    print("codes written by someone")

@my_annotation(author="Guido van Rossum")
def codeA():
    print("codes written by Guido van Rossum")

@my_annotation(author="虚拟WORLD-er")
def codeB():
    print("codes written by 虚拟WORLD-er")

# 分析程序是否被采用
def check_code(codes):
    author = codes.__annotations__.get("author")
    if author == None:
        print("代码未认证!")
    
    elif author == "Guido van Rossum":
        print("{}: 大佬代码!采用!".format(author))
    
    elif author == "虚拟WORLD-er":
        print("{}: 菜鸡代码!弃用!".format(author))
    
    else:
        print("待定...")

if __name__ == "__main__":
    check_code(codeC)
    check_code(codeA)
    check_code(codeB)

打印结果:

# 代码未认证!
# Guido van Rossum: 大佬代码!采用!
# 虚拟WORLD-er: 菜鸡代码!弃用!

python注解进阶可见:该文

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值