V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
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 ·
    czasg · Apr 27, 2021 · 2406 views
    This topic created in 1830 days ago, the information mentioned may be changed or developed.

    之前因为比较喜欢 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 replies    2021-04-28 10:33:28 +08:00
    TimePPT
        1
    TimePPT  
    PRO
       Apr 27, 2021   ❤️ 1
    xingheng
        2
    xingheng  
       Apr 27, 2021   ❤️ 1
    不需要 inspect,直接调用内置的 locals() 就行了
    est
        3
    est  
       Apr 27, 2021   ❤️ 1
    f"{name=}, {age=}"
    CzaOrz
        4
    CzaOrz  
    OP
       Apr 27, 2021
    @xingheng 在这个场景下 locals() 确实最佳,但是只涉及其中部分变量时,就还需要操作下了。
    CzaOrz
        5
    CzaOrz  
    OP
       Apr 27, 2021
    @TimePPT loguru 当时用过,因为要输出 json,所以直接自己写了个
    CzaOrz
        6
    CzaOrz  
    OP
       Apr 27, 2021
    @est f 赋值内部实现挺有意思的
    no1xsyzy
        7
    no1xsyzy  
       Apr 28, 2021
    写成装饰器(
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2514 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 08:14 · PVG 16:14 · LAX 01:14 · JFK 04:14
    ♥ Do have faith in what you're doing.