有没有方法写一个函数,能打印出传入变量的名称?

2019-10-25 14:44:51 +08:00
 JCZ2MkKb5S8ZX9pq
def show_var_info(var):
    # TODO return varName, varType, varContent
    varName = ???
    varType = type(var)
    print(f'{varName} {varType} {varContent}')
    

abc = 'test_content'
show_var_info(abc)

# Wish result:
# abc <class 'str'> test_content
3714 次点击
所在节点    Python
30 条回复
JCZ2MkKb5S8ZX9pq
2019-10-25 15:47:59 +08:00
@Trim21 虽然在函数内部这个功能没啥用,因为内部已经是 var 了。
不过 3.8 这个新功能不错,挺方便的。

上午刚好有看到一篇,才看了第一个海象,感觉用得不多。
JCZ2MkKb5S8ZX9pq
2019-10-25 15:49:52 +08:00
@Trim21 顺便问问现有代码到 3.8 向下兼容嘛?会有啥问题吗?没问题的话考虑升级了。
jiezhi
2019-10-25 15:51:38 +08:00
之前也有过这个需求,so 上也有答案,但觉得不是自己想要的解决方案,所以把自己需求改了。
Trim21
2019-10-25 15:57:22 +08:00
@JCZ2MkKb5S8ZX9pq 应该是兼容,不过有几个 break change,看你用到的库处理没处理了。

https://github.com/Qix-/better-exceptions 其实你的需求很像这个,但是这个库只是用来输出异常的
ClericPy
2019-10-25 16:12:13 +08:00
猛地一看还以为问的是 inspect.signature + vars() 的映射题...

仔细一想, 以前还真写过类似的装饰器, 通过 sys._getframe(stack_level).f_locals 在栈信息里找到所有局部变量, 然后与上面的 signature 一一对应就可以拿到了, 有点复杂, 不想写

解题思路:
sys._getframe(stack_level).f_locals 拿到当前函数外面的原是函数的 locals 变量, 然后与 inspect.signature 里一一对应, 得到变量的名称.
inspect.signature 是很详细的函数内省, 包括了变量的 type hints, 是否为 position only, 是否为 keyword only 等等
ClericPy
2019-10-25 16:15:54 +08:00
稍微看了眼评论... 为啥不用 PySnooper 呢?

以及 Python3.8 尽量别升, 旧项目很多不向后兼容的 deprecated issue, 需要升级依赖的库, 比如 abc 相关的 lxml 和
aiohttp. 如果是 Windows, 那 pip 的时候缺少 whl, 所以要本地编译, 很蛋疼. 如果开了 Travis CI 和 github 的 workflow 做测试, 直接报错 3.8 环境无法安装, 缺少安装源
wqzjk393
2019-10-25 16:31:50 +08:00
https://paste.ofcode.org/q5sXkHhp6vPKZXaNYMuFNR

又写了一个,直接读取文件,然后正则表达式找一下,因为会找到很多所以就封装一个 class 记录是第几次调用查找函数。。。。不过,StackOverflow 找到的答案说这种需求是无意义且不现实的。
yutou527
2019-10-25 16:41:12 +08:00
是不是可以故意写个异常,然后在 catch 里面获取 callstack 找到调用时的语句,然后解析出变量名?😄
necomancer
2019-10-26 06:23:58 +08:00
我有个很笨的办法,能不能在调用某个变量的时候用 locals/globals, 比如
a=2
f(x):
var = globals()[x]
do sth with var
...
调用时 x='a',即变量名。
ungrown
2021-01-08 12:24:27 +08:00
其实 stackoverflow 上已经有两个高价值帖子
https://stackoverflow.com/questions/1534504/convert-variable-name-to-string
https://stackoverflow.com/questions/18425225/getting-the-name-of-a-variable-as-a-string

除了 py3.8 开始支持的 f-string 中的`{name=}`特性之外,还有其他奇技淫巧,其中尤以 varname 这个库最为思路正确、做法成熟,它通过 executing 这个库,从 AST 这个层面着手,通过 AST 的 frame 、node 来定位具体变量所在代码,从而获取变量名乃至属性路径
https://pypi.org/project/varname/
https://github.com/pwwang/python-varname

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/612931

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX