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

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
3863 次点击
所在节点    Python
30 条回复
V2KN
2019-10-25 15:04:42 +08:00
python 2:

```python
from inspect import getcallargs

def show_var_info(var):
print getcallargs(show_var_info, var)


def wrapper(f, *args, **kwargs):
def inner(*args, **kwargs):
print getcallargs(f, *args, **kwargs)
return f(*args, **kwargs)
return inner

@wrapper
def foo(a):
print a * a
return a * a

@wrapper
def bar(a, b):
print a + b
return a + b

if __name__ == "__main__":
foo(3)
bar(1, 2)
```

输出:

```
{'a': 3}
9
{'a': 1, 'b': 2}
3
```

胡乱写的,不知道是不是你想要的……希望能帮到你……
V2KN
2019-10-25 15:06:20 +08:00
@V2KN 格式乱的,重新贴: https://pastebin.com/VdXGBDut
geelaw
2019-10-25 15:14:26 +08:00
不能,除非语言内部有一些这样的工具(我觉得多半是没有,你可以尝试自己挖掘 call stack 信息,但是一般来说这是一个很糟糕的想法)。

最简单的想法:var 的值所来自的表达式并不非要是一个变量表达式。
ttys001
2019-10-25 15:15:49 +08:00
在 globals()/locals()里找可以嘛,类似 list(globals().keys())[list(globals().values()).index(abc)],有重复的再改改…
wqzjk393
2019-10-25 15:16:30 +08:00
def func1(para):
global_dirc = globals().copy()
for each in global_dirc.keys():
if global_dirc[each] is para:
return each,type(para),para
return -1

话说你投错区了吧,你这写法好像是 js。。。。
GrassSand
2019-10-25 15:17:58 +08:00
hakono
2019-10-25 15:20:30 +08:00
@wqzjk393
这方法是不可行的
```
a = 10
b = 10
print(func1(b))
```
输出 ('a', <class 'int'>, 10)
因为 is 的作用是查找内存快中位置
Vegetable
2019-10-25 15:22:59 +08:00
可以说一下你的 X 问题吗?这个 Y 大家都觉得很奇怪
ipwx
2019-10-25 15:23:58 +08:00
提供思路

第一步:通过 callstack 得到调用函数的那句话所在的源文件和行号。
第二部:通过 ast 解析调用的语句。
第三部:你已经拿到所有需要的信息了,可以输出了。
ipwx
2019-10-25 15:24:51 +08:00
没有别的方法。看起来楼主你是从 C/C++ 转过来的,因为常见语言估计也只有 C/C++ 的宏能很简单地做到这件事情了。
JCZ2MkKb5S8ZX9pq
2019-10-25 15:26:14 +08:00
@wqzjk393 我只是变量简写为 var 而已
另外你这个方法,我试了下,如果碰到值一样的变量,就会只取第一个。
JCZ2MkKb5S8ZX9pq
2019-10-25 15:26:54 +08:00
@V2KN 大哥,不用 py2 好久了。
Vegetable
2019-10-25 15:28:44 +08:00
函数的参数有些时候是表达式,比如 fun(1),这个时候 1 只是一个值。
JCZ2MkKb5S8ZX9pq
2019-10-25 15:29:48 +08:00
@Vegetable 就是单纯地想输出一些信息,又想少一些重复输入。
不知道 logging 有没有相关的方法,我找找。
hakono
2019-10-25 15:30:37 +08:00
@JCZ2MkKb5S8ZX9pq 你这需求其实并不靠谱,因为即便真的 python 能做到这种事,那么
show_var_info(999)
show_var_info([1,2,3,4,5])

etc...

这时候你希望获得怎样的变量名?
JCZ2MkKb5S8ZX9pq
2019-10-25 15:31:34 +08:00
@geelaw 考虑过丢 str(var)进去,然后再回头去全局找,但也有点绕。而且有可能找错。
JCZ2MkKb5S8ZX9pq
2019-10-25 15:32:46 +08:00
@hakono 是的,在函数内部,其实得不到变量名,就是得到了具体的值,或者说是一个新的变量 var。
chengyiqun
2019-10-25 15:35:14 +08:00
混淆以后就没意义了
Trim21
2019-10-25 15:39:00 +08:00
3.8 的 f string 新特性
Vegetable
2019-10-25 15:40:53 +08:00
也许这个设计是你想要的东西,一般 debug 的时候,比如 Django,报错之后输出的是调用栈和每一层调用的 locals,这样的形式也是很清晰的,不过也是没有表达式的,只有变量。

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

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

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

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

© 2021 V2EX