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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1665833/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 22:49:47  来源:igfitidea点击:

How do I get the string representation of a variable in python?

pythonintrospection

提问by Johan

I have a variable x in python. How can i find the string 'x' from the variable. Here is my attempt:

我在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()

The results are:

结果是:

Global var x = 123
Local var x = 321

The above recipe seems a bit un-pythonesque. Is there a better/shorter way to achieve the same result?

上面的食谱似乎有点非蟒蛇式。有没有更好/更短的方法来实现相同的结果?

回答by steveha

Q: I have a variable x in python. How can i find the string 'x' from the variable.

问:我在 python 中有一个变量 x。如何从变量中找到字符串“x”。

A: If I am understanding your question properly, you want to go from the value of a variable to its name. This is not really possible in Python.

答:如果我正确理解您的问题,您想从变量的值到其名称。这在 Python 中是不可能的。

In Python, there really isn't any such thing as a "variable". What Python really has are "names" which can have objects bound to them. It makes no difference to the object what names, if any, it might be bound to. It might be bound to dozens of different names, or none.

在 Python 中,确实没有任何诸如“变量”之类的东西。Python 真正拥有的是可以绑定对象的“名称”。对象的名称(如果有)可能绑定到什么名称没有任何区别。它可能绑定到几十个不同的名称,或者一个都没有。

Consider this example:

考虑这个例子:

foo = 1
bar = foo
baz = foo

Now, suppose you have the integer object with value 1, and you want to work backwards and find its name. What would you print? Three different names have that object bound to them, and all are equally valid.

现在,假设您有一个值为 1 的整数对象,并且您想逆向工作并找到它的名称。你会打印什么?三个不同的名称都绑定了该对象,并且都同样有效。

print(bar is foo) # prints True
print(baz is foo) # prints True

In Python, a name is a way to access an object, so there is no way to work with names directly. You might be able to search through locals()to find the value and recover a name, but that is at best a parlor trick. And in my above example, which of foo, bar, and bazis the "correct" answer? They all refer to exactly the same object.

在 Python 中,名称是访问对象的一种方式,因此无法直接使用名称。您也许可以通过搜索locals()来查找值并恢复名称,但这充其量只是一个客厅技巧。而在我上面的例子中,其中foobarbaz是“正确”的答案?它们都指向完全相同的对象。

P.S. The above is a somewhat edited version of an answer I wrote before.I think I did a better job of wording things this time.

PS 以上是我之前写的答案的稍微编辑版本我认为这次我在措辞方面做得更好。

回答by Gabriel Hurley

I believe the general form of what you want is repr()or the __repr__()method of an object.

我相信您想要的一般形式repr()__repr__()对象的方法。

with regards to __repr__():

关于__repr__()

Called by the repr() built-in function and by string conversions (reverse quotes) to compute the “official” string representation of an object.

由 repr() 内置函数和字符串转换(反引号)调用以计算对象的“官方”字符串表示。

See the docs here: object.repr(self)

请参阅此处的文档:对象。代表(自我)

回答by Matt Anderson

stevenha has a great answer to this question. But, if you actually do want to poke around in the namespace dictionaries anyway, you can get all the names for a given value in a particular scope / namespace like this:

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

If you're working with a Python that has stack frame support (most do, CPython does), it isn't required that you pass the locals dict into the names_offunction; the function can retrieve that dictionary from its caller's frame itself:

如果您正在使用具有堆栈帧支持的 Python(大多数支持,CPython 支持),则不需要将 locals dict 传递给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']

If you're working with a value type that you can assign a name attribute to, you can give it a name, and then use that:

如果您正在使用可以为其分配 name 属性的值类型,则可以为其指定一个名称,然后使用它:

class SomeClass(object):
    pass

obj = SomeClass()
obj.name = 'obj'


class NamedInt(int):
    __slots__ = ['name']

x = NamedInt(321)
x.name = 'x'

Finally, if you're working with class attributes and you want them to know their names (descriptors are the obvious use case), you can do cool tricks with metaclass programming like they do in the Django ORM and SQLAlchemy declarative-style table definitions:

最后,如果您正在使用类属性并且希望它们知道它们的名称(描述符是明显的用例),您可以使用元类编程来做一些很酷的技巧,就像它们在 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'

回答by elzapp

There are three ways to get "the" string representation of an object in python: 1: str()

在python中有三种方法可以获取对象的“the”字符串表示形式:1:str()

>>> foo={"a":"z","b":"y"}
>>> str(foo)
"{'a': 'z', 'b': 'y'}"

2: repr()

2:repr()

>>> foo={"a":"z","b":"y"}
>>> repr(foo)
"{'a': 'z', 'b': 'y'}"

3: string interpolation:

3:字符串插值:

>>> foo={"a":"z","b":"y"}
>>> "%s" % (foo,)
"{'a': 'z', 'b': 'y'}"

In this case all three methods generated the same output, the difference is that str() calls dict.__str__(), while repr() calls dict.__repr__(). str() is used on string interpolation, while repr() is used by Python internally on each object in a list or dict when you print the list or dict.

在这种情况下,所有三种方法都生成相同的输出,区别在于 str() 调用dict.__str__(),而 repr() 调用dict.__repr__(). str() 用于字符串插值,而 repr() 由 Python 在您打印列表或字典时在列表或字典中的每个对象内部使用。

As Tendayi Mawushe mentiones above, string produced by repr isn't necessarily human-readable.

正如 Tendayi Mawushe 上面提到的,repr 生成的字符串不一定是人类可读的。

Also, the default implementation of .__str__()is to call .__repr__(), so if the class does not have it's own overrides to .__str__(), the value returned from .__repr__()is used.

此外, 的默认实现.__str__()是调用.__repr__(),因此如果该类没有自己的 覆盖.__str__().__repr__()则使用从 返回的值。