2012-07-02 10 views
6

me gustaría hacer lo siguiente:Python 2.7 utilizando la entrada a una función como una cadena y variables

print "CC =",CC 

sino como una función de manera que sólo tengo para escribir la variable CC vez. No puedo averiguar cómo hacer esto en una función, ya que siempre evalúa CC como un número de punto flotante (que es) .... ¿Hay alguna manera de aceptar la entrada a una función como cadena y punto flotante? ¿número?

yo probamos este:

def printme(a): 
    b='%s' % a 
    print b 
    return b 

pero por supuesto que sólo imprime el valor de a, no su nombre.

+2

Python se escribe de forma dinámica, por lo que la respuesta es "Sí, por supuesto!". La respuesta larga depende de lo que haya intentado, ¿podría compartir lo que hizo y lo que salió mal y lo que esperaba en su lugar? –

+0

que han intentado varias cosas, aquí es donde estoy tratando de imprimir la cadena y el número de coma flotante, pero los resultados en la impresión de punto flotante y sin cadena: – malby

+0

def PrintMe (a): b = '% s', una print b return b – malby

Respuesta

0

Si te entiendo correctamente, ¿quieres algo como esto?

def f(a): 
    print('{0}: = {1}'.format(locals().keys()[0], a)) 

Actualización:

Soy consciente de que el ejemplo no tiene mucho sentido, ya que es básicamente el mismo que:

def f(a): 
    print('a: {0}'.format(a)) 

Simplemente quería señalar la OP a los lugareños() ya que no entendí muy bien lo que él está tratando de lograr.

supongo que esto es más de lo que está buscando:

def f(**kwargs): 
    for k in kwargs.keys(): 
     print('{0}: {1}'.format(k, kwargs[k])) 


f(a=1, b=2) 
+1

esto no funcionará ya que la variable no está en el ámbito local de la función – l4mpi

+0

Esto es exactamente lo mismo que escribir 'print' a =% s '% a' ya que el nombre local siempre será' a '. Si esto realmente es lo que quiere el OP, entonces no se puede hacer debido a la forma en que funciona Python. –

+0

esto no funcionará, el nombre local siempre será 'a'. –

0

No es exactamente lo que quiere, pero fácil de hacer:

def printme(**kwargs): 
    for key, value in kwargs.items(): 
     print '%s=%s' % (key, value) 
    return value 

In [13]: printme(CC=1.23, DD=2.22) 
CC=1.23 
DD=2.22 
Out[13]: 1.23 
1

un diccionario Tal vez es una mejor aproximación al problema. Asumiendo que tiene varios pares de nombre y valor que desea utilizar, puede ponerlos en una dict:

params = {"CC": 1.2345, "ID": "Yo!", "foo": "bar"} 

Entonces, por ejemplo, podría imprimir todos los nombres y valores con un formato agradable como esto:

for key in params: 
    print "{0} = {1}".format(key, params[key]) 

Pero como todavía no está claro por qué está tratando de hacer esto, es difícil decir si es la manera correcta.

+1

El motivo es que solo tengo que escribir CC una vez y no dos. Haré esto mucho así que la taquigrafía es útil, la aplicación que uso python es la informática científica, así que cuando se codifican algoritmos matemáticos se hace todo el tiempo para depurar, en Matlab, por ejemplo, esto es muy simple, ya que solo se escribe el nombre de la variable y matlab devuelve su valor. – malby

+2

+1 Esto no es lo que quiere OP, pero esto es lo que OP debería hacer. He visto muchas preguntas similares a esta en SO y cada una de ellas termina con la decisión de que el uso de un dict es la forma más conveniente y más pitónica de resolver el problema. – Vader

+0

@Vader, no veo cómo esta pregunta es sobre el formato de cadenas. El problema de OP es cómo * obtener * el nombre y el valor de la variable dentro de una función sin proporcionar * both * explícitamente ("¿Hay alguna manera de aceptar la entrada a una función como cadena y número de punto flotante" y "... .de modo que solo tengo que escribir la variable CC una vez "). – catchmeifyoutry

0

Si lo entiendo correctamente, ¿quiere una abreviatura para imprimir un nombre de variable y su valor en el alcance actual? En general, esto es imposible sin utilizar la función de rastreo de intérpretes o sys._getframe, que en general solo debe utilizarse si sabe lo que está haciendo. La razón de esto es que la función de impresión no tiene otra manera de conseguir los locales del ámbito de llamar:

def a(): 
    x = 1 
    magic_print("x") #will not work without accessing the current frame 

lo que puede hacer sin que éstos se pasan de forma explícita a los locales a una función como esta:

def printNameAndValue(varname, values): 
    print("%s=%s" % (varname, values[varname])) 

def a(): 
    x = 1 
    printNameAndValue("x", locals()) #prints 'x=1' 

EDIT:

ver la respuesta por catchemifyoutry de una solución mediante el módulo de inspección (que utiliza internamente sys._getframe).Para completar una solución utilizando la función de rastreo directamente - útil si estás usando Python 2.0 e inspeccionar no está disponible;)

from sys import settrace 

__v = {} #global dictionary that holds the variables 

def __trace(frame, event, arg): 
    """ a trace function saving the locals on every function call """ 
    global __v 
    if not event == "call": 
     return __trace 
    __v.update(frame.f_back.f_locals) 

def enableTrace(f): 
    """ a wrapper decorator setting and removing the trace """ 
    def _f(*a, **kwa): 
     settrace(__trace) 
     try: 
      f(*a, **kwa) 
     finally: 
      settrace(None) 
    return _f 

def printv(vname): 
    """ the function doing the printing """ 
    global __v 
    print "%s=%s" % (vname, __v[vname]) 

guardarlo en un módulo y utilizar así:

from modulenamehere import enableTrace, printv 

@enableTrace 
def somefunction(): 
    x = 1 
    [...] 
    printv("x") 
+0

mmm, gracias por el esfuerzo, creo que tiene razón en que no hay solución, me parece que ahora que mi solución original es la mejor, la dificultad surge debido a que python suprime todas las entradas por defecto, en realidad es la una forma de desactivar esto? – malby

+0

No tiene idea de lo que quiere decir con 'suprimir todas las entradas', pero vea la respuesta de @catchmeifyoutry para una solución que utiliza inspeccionar (que internamente usa la función de rastreo). – l4mpi

0

se utiliza una variable global para lograr esto, func.__globals__.keys() contiene todas las variables pasadas al func, así que filtran el nombre startin con __ y los almacena en una lista. con cada llamada a func() el func.__globals__.keys() se actualiza con el nuevo nombre de variable, así que compare el nuevo varn con el anterior resultados en la nueva variable que se acaba de agregar.

glo=[] 
def func(x): 
    global glo 
    varn=[x for x in func.__globals__.keys() if not x.startswith('__') and x!=func.__name__] 
    new=list(set(varn)^set(glo)) 
    print("{0}={1}".format(new[0],x)) 
    glo=varn[:] 

de salida:

>>> a=10 
>>> func(a) 
a=10 
>>> b=20 
>>> func(20) 
b=20 
>>> foo='cat' 
>>> func(foo) 
foo=cat 
>>> bar=1000 
>>> func(bar) 
bar=1000 
3

podría utilizar el módulo de inspect (véase también this SO question):

def printme(x): 
    import inspect 
    f = inspect.currentframe() 
    val = f.f_back.f_locals[x] 
    print x, '=', val 


CC = 234.234  
printme('CC') # <- write variable name only once 
# prints: CC = 234.234 
1

Creo que esta es la solución requerida:

def printme(x): 
    keys_list = [key for key, value in globals().iteritems() if value == x] 
    print keys_list 
    for key in keys_list: 
     if id(globals()[key]) == id(x): 
      result = "%s = %s" %(key, x) 
      print result 
      break 

    return result 

por ejemplo, si se declara una variable:

>>> c=55.6 

continuación, resultado de PrintMe (c) habrá

>>> 'c = 55.6' 

Nota: Esta solución se basa en la coincidencia de ID único a nivel mundial.

+0

esto solo funciona si la variable está en 'globales ', lo que significa que no sirve para locales de funciones ... – l4mpi

+0

@ l4mpi Según la pregunta formulada, se pasará una variable a una función. Esto significa que esa variable no estará en los locales() de esa función, sino en las globales(). Así que revisé los globals() primero. Esta no podría ser la solución exacta, pero creo que puede dar la solución requerida mediante pequeñas modificaciones, es decir, verificar locals() primero. –

+0

esto está mal y demuestra su poca comprensión del alcance variable. la variable solo estará en 'globales 'si se declara en el nivel de módulo (o explícitamente declarada como global). si la variable se declara dentro de otra función, no estará en 'globals' ni dentro de' locales' de su función de impresión - intente 'def f (x): printme (x)' y luego llame a 'f (1)'. ver la respuesta de catchmeifyoutrys para una solución real utilizando los locales del alcance de la llamada. – l4mpi

Cuestiones relacionadas