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
CzaOrz
V2EX  ›  Python

分享:如何取出变量的变量名,自动赋值到结构化日志中

  •  
  •   CzaOrz ·
    CzaOrz · 15 天前 · 611 次点击

    之前因为比较喜欢 golang 的结构化日志模块 logrus,所以模仿写了个 loggus
    最近项目原因,写了一段时间的 golang,又回到 python 中...

    于是又接触到了自己写的 loggus,然后写了很多类似这样的代码

    import loggus
    
    def userInfo(name, age, phone):
        loggus.withFields({
            "name": name,
            "age": age,
            "phone": phone,
        }).info("0.0")
    
    userInfo("小明", 18, 10086)
    # 输出
    # time="2021-04-27 15:02:17.671655" level=info msg="0.0" name="小明" age=18 phone=10086
    

    我自己写着写着发现,为结构化日志赋值时,很多 key 值,和变量的变量名是相同的,但我不得不重新写一遍。
    就像上面的那个字典:

    {
        "name": name,
        "age": age,
        "phone": phone,
    }
    

    于是近期就在思考:是否可以自动取出该变量的变量名,自行完成赋值操作?

    参考了较多的文章和 logging 源码之后,发现有一条思路是值得借鉴的:通过回溯调用栈,找到调用函数的源码,通过正则取出所需变量名,然后进行赋值。

    最后实现了一个神奇的方法 loggus.withVariables,类似这样:

    import loggus
    
    def userInfo(name, age, phone):
        loggus.withVariables(name, age, phone).info("0.0")
        # 输出
        # time="2021-04-27 14:38:05.400769" level=info msg="0.0" name="小明" age=18 phone=10086
    
        loggus.withVariables(
            name,
            age,
            phone,
        ).info("0.0")
        # 输出
        # time="2021-04-27 14:38:05.400769" level=info msg="0.0" name="小明" age=18 phone=10086
    
    if __name__ == '__main__':
        userInfo("小明", 18, 10086)
    

    最后总结:花里胡哨没啥用,哈哈哈
    有兴趣的可以看下实现: https://github.com/CzaOrz/loggus

    7 条回复    2021-04-28 10:33:28 +08:00
    TimePPT
        1
    TimePPT   15 天前   ❤️ 1
    xingheng
        2
    xingheng   15 天前   ❤️ 1
    不需要 inspect,直接调用内置的 locals() 就行了
    est
        3
    est   15 天前   ❤️ 1
    f"{name=}, {age=}"
    CzaOrz
        4
    CzaOrz   15 天前
    @xingheng 在这个场景下 locals() 确实最佳,但是只涉及其中部分变量时,就还需要操作下了。
    CzaOrz
        5
    CzaOrz   15 天前
    @TimePPT loguru 当时用过,因为要输出 json,所以直接自己写了个
    CzaOrz
        6
    CzaOrz   15 天前
    @est f 赋值内部实现挺有意思的
    no1xsyzy
        7
    no1xsyzy   14 天前
    写成装饰器(
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1004 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 19:37 · PVG 03:37 · LAX 12:37 · JFK 15:37
    ♥ Do have faith in what you're doing.