V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
guyskk
V2EX  ›  Python

Python 3 的函数 Annotations 还可以这样用

  •  
  •   guyskk ·
    guyskk · 2017-03-25 19:19:31 +08:00 · 2019 次点击
    这是一个创建于 2806 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Python 3.5 开始支持 Annotations ,可以用来给函数参数加上注解,也有一个叫 mypy 的库用它来做静态类型检查。

    前几天发布 Validr 0.14.0 版,在 reddit 上也有人问支不支持 mypy ,今天突发奇想写了个用来运行时检查参数和返回值。

    一个简单的实现:

    # python >= 3.5
    # pip install validr
    from validr import SchemaParser, mark_key
    
    
    def validation(f):
        """Decorator for validate function params and return by __annotations__"""
        parser = SchemaParser()
        return_ = None
        params = {}
        for k, v in f.__annotations__.items():
            if k == 'return':
                return_ = parser.parse(v)
            else:
                params[k] = parser.parse(v)
    
        def wrapper(**kwargs):
            for k, v in params.items():
                with mark_key(k):
                    kwargs[k] = v(kwargs.get(k, None))
            result = f(**kwargs)
            if return_:
                with mark_key('return'):
                    result = return_(result)
            return result
        return wrapper
    
    
    @validation
    def login(
        username: 'str',
        password: 'str&minlen=6',
    ) -> {
        'id?int': 'User ID',
    }:
        return {'id': 1000000}
    
    
    if __name__ == '__main__':
        print(login(username='guyskk', password='123456'))
        print(login(username='guyskk', password='1234'))
    

    另外这种写法也是能实现的:

    @validation
    def login(
        username: StringType(),
        password: StringType(minlen=6),
    ) -> {
        'id': IntType(desc='User ID'),
    }:
        return {'id': 1000000}
    

    大家觉得这两个写法怎么样,有需要这样一个库的吗

    guyskk
        1
    guyskk  
    OP
       2017-03-25 20:25:50 +08:00
    打算放弃这种写法 -> 还不如直接写 go 算了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1030 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 19:29 · PVG 03:29 · LAX 11:29 · JFK 14:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.