簡體   English   中英

如何在python中獲取變量的字符串表示?

[英]How do I get the string representation of a variable in 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中有一個變量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中的哪一個是“正確的”答案? 它們都指的是完全相同的對象。

PS以上是我之前寫過的一個有點編輯的答案版本 我想這次我的措辭做得更好了。

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

關於__repr__()

由repr()內置函數和字符串轉換(反向引號)調用,以計算對象的“官方”字符串表示形式。

請參閱此處的文檔: 對象。 repr (個體經營)

史蒂文哈對這個問題有很好的答案。 但是,如果您確實想要在命名空間字典中查找,那么您可以獲取特定范圍/命名空間中給定值的所有名稱,如下所示:

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

如果您正在使用可以為其指定名稱屬性的值類型,則可以為其指定名稱,然后使用:

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'

有三種方法可以在python中獲取對象的“字符串”表示形式:1:str()

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

2:repr()

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

3:字符串插值:

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

在這種情況下,所有三個方法都生成相同的輸出,區別在於str()調用dict.__str__() ,而repr()調用dict.__repr__() str()用於字符串插值,而repr()在打印列表或字典時由Python內部用於列表或字典中的每個對象。

正如Tendayi Mawushe上面提到的那樣,repr生成的字符串不一定是人類可讀的。

此外, .__str__()的默認實現是調用.__repr__() ,因此如果類沒有自己覆蓋.__str__() ,則使用從.__repr__()返回的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM