2009-11-03 38 views
6

我在Python中有一个变量x。我如何从变量中找到字符串'x'。这里是我的尝试:如何在python中获取变量的字符串表示形式?

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 

以上配方似乎有点非pythonesque。是否有更好/更短的方法来达到相同的结果?

+2

你真的想要做什么?没有'x'没有调用,所以你可以使用print'var x =%s'%x,但是你不需要。为什么? – tuergeist 2009-11-03 07:53:22

+0

重复:http://stackoverflow.com/questions/1534504/convert-variable-name-to-string – 2009-11-03 08:22:26

+0

重复太http://stackoverflow.com/questions/592746/how-can-you-print-a-variable -name-in-python-closed – fortran 2009-11-03 11:14:07

回答

13

问:我有一个变量x的蟒蛇。我如何从变量中找到字符串'x'。 A:如果我正确理解你的问题,你想从一个变量的值到它的名字。这在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中的哪一个是“正确的”答案?它们都指的是完全相同的对象。

P.S.以上是an answer I wrote before.的某种编辑版本,我认为这次我的表述做得更好。

+0

是的,这可以使用locals()函数。它返回本地作用域中所有变量(包括对象,方法和函数)的字典。 – elzapp 2009-11-03 10:13:10

+0

感谢您的回复。我在不同的轨道上被带走了。你以前的文章改变了我想要做的事情。 – Johan 2009-11-03 15:30:40

7

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

至于__repr__()

由再版(被叫)内置函数 并串转换(反向 引号)来计算对象的“正式” 字符串表示。

在这里看到的文档:object.repr(self)

+0

是的,这是我对OP问题的解释以及。您可以使用repr()作为对象的python语句表示形式,str()作为ascii字符串表示形式,unicode()作为Unicode字符串表示形式。 – btk 2012-03-14 02:58:53

0

有三种方式来获得 “该” 在python的对象的字符串表示: 1:STR()

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

2:再版()

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

3:串内插:

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

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

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

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都支持),但不要求您将本地代码转换为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'] 

如果你使用,你可以在name属性分配一个值类型的工作,你可以给它一个名称,然后使用:

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' 
相关问题