如何在Python中获取变量的字符串表示?
我在Python里有一个变量x。我该怎么从这个变量中找到字符串'x'呢?这是我尝试的方法:
def var(v,c):
for key in c.keys():
if c[key] == v:
return key
def f():
x = '321'
print 'Local var %s = %s'%(var(x,locals()),x)
x = '123'
print 'Global var %s = %s'%(var(x,locals()),x)
f()
结果是:
Global var x = 123
Local var x = 321
上面的做法看起来有点不太像Python的风格。有没有更好或者更简洁的方法来达到同样的效果呢?
4 个回答
stevenha 对这个问题有一个很好的回答。不过,如果你真的想在命名空间字典里看看,可以用下面的方法获取特定范围/命名空间中某个值的所有名字:
def foo1():
x = 5
y = 4
z = x
print names_of1(x, locals())
def names_of1(var, callers_namespace):
return [name for (name, value) in callers_namespace.iteritems() if var is value]
foo1() # prints ['x', 'z']
如果你使用的是支持栈帧的 Python(大多数都是,CPython 也支持),那么你不需要把 locals 字典传递给 names_of
函数;这个函数可以直接从调用它的栈帧中获取那个字典:
def foo2():
xx = object()
yy = object()
zz = xx
print names_of2(xx)
def names_of2(var):
import inspect
callers_namespace = inspect.currentframe().f_back.f_locals
return [name for (name, value) in callers_namespace.iteritems() if var is value]
foo2() # ['xx', 'zz']
如果你使用的是可以赋予名字属性的值类型,你可以给它一个名字,然后使用这个名字:
class SomeClass(object):
pass
obj = SomeClass()
obj.name = 'obj'
class NamedInt(int):
__slots__ = ['name']
x = NamedInt(321)
x.name = 'x'
最后,如果你在处理类属性,并且想让它们知道自己的名字(描述符就是一个明显的用例),你可以用元类编程做一些很酷的技巧,就像 Django ORM 和 SQLAlchemy 的声明式表定义那样:
class AutonamingType(type):
def __init__(cls, name, bases, attrs):
for (attrname, attrvalue) in attrs.iteritems():
if getattr(attrvalue, '__autoname__', False):
attrvalue.name = attrname
super(AutonamingType,cls).__init__(name, bases, attrs)
class NamedDescriptor(object):
__autoname__ = True
name = None
def __get__(self, instance, instance_type):
return self.name
class Foo(object):
__metaclass__ = AutonamingType
bar = NamedDescriptor()
baaz = NamedDescriptor()
lilfoo = Foo()
print lilfoo.bar # prints 'bar'
print lilfoo.baaz # prints 'baaz'
我觉得你想要的东西大概就是 repr()
或者对象的 __repr__()
方法。
关于 __repr__()
:
这个方法是通过内置的 repr() 函数调用的,也可以通过字符串转换(反引号)来计算对象的“官方”字符串表示。
你可以在这里查看文档:object.repr(self)
问:我在Python中有一个变量x。我怎么才能从这个变量中找到字符串'x'?
答:如果我理解你的问题没错,你是想从一个变量的值找到它的名字。在Python中,这其实是做不到的。
在Python里,实际上并没有“变量”这个概念。Python真正有的是“名字”,这些名字可以和对象关联起来。对于对象来说,它并不在乎自己被绑定了多少个名字,或者根本没有名字。
举个例子:
foo = 1
bar = foo
baz = foo
现在,假设你有一个值为1的整数对象,你想反向查找它的名字。你会打印出什么呢?有三个不同的名字都和这个对象关联,它们都是有效的。
print(bar is foo) # prints True
print(baz is foo) # prints True
在Python中,名字是用来访问对象的方式,所以你无法直接操作名字。你可能可以通过locals()
来查找值并找回一个名字,但这充其量只是个小把戏。而在我上面的例子中,foo
、bar
和baz
哪个是“正确”的答案呢?它们都指向完全相同的对象。
附注:以上内容是我之前写的一个回答的稍微编辑版,链接在这里。 我觉得这次我表达得更清楚了。