2009-11-03 12 views
6

Ho una variabile x in python. Come posso trovare la stringa 'x' dalla variabile. Qui è il mio tentativo:Come ottengo la rappresentazione della stringa di una variabile in 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() 

I risultati sono:

Global var x = 123 
Local var x = 321 

La ricetta di cui sopra sembra un po 'un-Pythonesque. C'è un modo migliore/più breve per ottenere lo stesso risultato?

+2

Cosa vuoi davvero? Non c'è una chiamata senza una 'x', quindi puoi usare print 'var x =% s'% x ma non lo fai. Perché? – tuergeist

+0

duplicato: http://stackoverflow.com/questions/1534504/convert-variable-name-to-string –

+0

duplicato anche http://stackoverflow.com/questions/592746/how-can-you-print-a-variable -name-in-python-closed – fortran

risposta

13

D: Ho una variabile x in python. Come posso trovare la stringa 'x' dalla variabile.

A: Se sto capendo correttamente la tua domanda, vuoi passare dal valore di una variabile al suo nome. Questo non è realmente possibile in Python.

In Python, non esiste realmente una "variabile". Quello che Python ha veramente sono i "nomi" che possono avere degli oggetti legati a loro. Non fa differenza per l'oggetto quali nomi, se ce ne sono, potrebbero essere vincolati a. Potrebbe essere associato a dozzine di nomi diversi o nessuno.

Considerate questo esempio:

foo = 1 
bar = foo 
baz = foo 

Ora, si supponga di avere l'oggetto intero con il valore 1, e si vuole lavorare a ritroso e di trovare il suo nome. Cosa stamperesti? Tre nomi diversi hanno quell'oggetto legato a loro, e tutti sono ugualmente validi.

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

In Python, un nome è un modo per accedere a un oggetto, quindi non c'è modo di lavorare con i nomi direttamente. Potrebbe essere possibile cercare attraverso locals() per trovare il valore e recuperare un nome, ma nel migliore dei casi è un trucco da salotto. E nel mio esempio precedente, quale di foo, bar e baz è la risposta "corretta"? Si riferiscono tutti esattamente allo stesso oggetto.

P.S. Quanto sopra è una versione leggermente modificata di an answer I wrote before. Penso che questa volta abbia fatto un lavoro migliore di parole.

+0

Sì, è possibile utilizzare la funzione locals(). Restituisce un dizionario di tutte le variabili nell'ambito locale (inclusi oggetti, metodi e funzioni). – elzapp

+0

Grazie per la risposta. Sono stato portato via su una pista diversa. Il tuo post precedente mi ha cambiato idea su cosa volevo fare. – Johan

7

Credo che la forma generale di ciò che si desidera sia repr() o il metodo __repr__() di un oggetto.

con riferimento a __repr__():

Chiamato repr() funzione incorporata e conversioni di stringhe (reverse virgolette) per calcolare la rappresentazione stringa “ufficiale” di un oggetto.

Vedere la documentazione qui: object.repr(self)

+0

Sì, questa è la mia interpretazione della domanda OPs anche. È possibile utilizzare repr() per la rappresentazione dell'istruzione python dell'oggetto, str() per la rappresentazione della stringa ascii e unicode() per la rappresentazione della stringa Unicode. – btk

0

Ci sono tre modi per ottenere "la" rappresentazione stringa di un oggetto in pitone: 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: interpolazione stringa :

In questo caso tutti e tre i metodi hanno generato la stessa uscita, il di la differenza è che str() chiama dict.__str__(), mentre repr() chiama dict.__repr__(). str() è usato sull'interpolazione delle stringhe, mentre repr() è usato da Python internamente su ogni oggetto in un elenco o dict quando si stampa l'elenco o il comando.

Come menzionato in precedenza da Tendayi Mawushe, la stringa prodotta da repr non è necessariamente leggibile dall'uomo.

3

stevenha ha una grande risposta a questa domanda. Ma, se effettivamente si vuole frugare nei dizionari namespace in ogni caso, è possibile ottenere tutti i nomi per un dato valore in un determinato ambito/namespace in questo modo:

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

Se si lavora con un pitone che ha il supporto per lo stack frame (la maggior parte lo fa, CPython lo fa), non è necessario passare la gente del posto nella funzione names_of; la funzione può recuperare quel dizionario dal telaio del chiamante stesso:

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

Se si sta lavorando con un tipo di valore che è possibile assegnare un attributo name per, si può dare un nome, e quindi utilizzare tale:

class SomeClass(object): 
    pass 

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


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

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

Infine, se si sta lavorando con gli attributi di classe e si desidera loro di conoscere i loro nomi (descrittori sono il caso d'uso ovvio), si può fare trucchetti con la programmazione metaclasse come fanno in Django ORM e SQLAlchemy definizioni di tabelle in stile dichiarativo:

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