2009-11-03 65 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' 
相關問題