如何在Python中获取变量的字符串表示?

7 投票
4 回答
22750 浏览
提问于 2025-04-15 15:37

我在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 个回答

3

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'
7

我觉得你想要的东西大概就是 repr() 或者对象的 __repr__() 方法。

关于 __repr__()

这个方法是通过内置的 repr() 函数调用的,也可以通过字符串转换(反引号)来计算对象的“官方”字符串表示。

你可以在这里查看文档:object.repr(self)

14

问:我在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()来查找值并找回一个名字,但这充其量只是个小把戏。而在我上面的例子中,foobarbaz哪个是“正确”的答案呢?它们都指向完全相同的对象。

附注:以上内容是我之前写的一个回答的稍微编辑版,链接在这里。 我觉得这次我表达得更清楚了。

撰写回答