简体   繁体   English

Python 2.7使用函数的输入作为字符串和变量

[英]Python 2.7 using the input to a function as a string and variable

I would like to do the following: 我想做以下事情:

print "CC =",CC

but as a function so that i only have to write the variable CC once. 但作为一个函数,我只需要写一次变量CC。 I can't work out how to do this in a function as it always evaluates CC as a floating point number (which it is).... Is there a way to accept the input to a function as both a string and floating point number? 我无法弄清楚如何在函数中执行此操作,因为它总是将CC计算为浮点数(它是)....有没有办法接受函数的输入作为字符串和浮点数?

I tried this: 我试过这个:

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

but of course it only prints the value of a , not its name. 但当然只打印的值a ,而不是它的名称。

You could use the inspect module (see also this SO question ): 您可以使用检查模块(另请参阅此SO问题 ):

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

Perhaps a dictionary is a better approach to the problem. 也许字典是解决问题的更好方法。 Assuming you have several name-value pairs that you want to use, you can put them in a dict : 假设您有几个要使用的名称 - 值对,可以将它们放在一个dict

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

Then, for example, you could print all the names and values nicely formatted like this: 然后,例如,您可以打印所有格式良好的名称和值,如下所示:

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

But since it is still unclear why you are trying to do this, it's hard to tell whether this is the right way. 但由于目前仍不清楚为什么要这样做,因此很难判断这是否是正确的方法。

I think this is your required solution: 我认为这是您需要的解决方案:

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

for example if you declare a variable: 例如,如果您声明一个变量:

>>> c=55.6

then result of printme(c) will be 然后printme(c)的结果将是

>>> 'c = 55.6'

Note: This solution is based on globally unique id matching. 注意:此解决方案基于全局唯一ID匹配。

If I understand you correctly you want something like this? 如果我理解你,你想要这样的东西吗?

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

Update: 更新:

I am aware that the example doesn't make a lot of sense, as it's basically the same as: 我知道这个例子没有多大意义,因为它基本上与以下内容相同:

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

I merely wanted to point the OP to locals() as I didn't quite understand what he's trying to accomplish. 我只是想把OP指向本地人(),因为我不太明白他想要完成什么。

I guess this is more what he's looking for: 我想这更像是他在寻找的东西:

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


f(a=1, b=2)

Not exactly what you want, but easy to do: 不完全是你想要的,但很容易做到:

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

If I understand you correctly you want a shorthand for printing a variable name and its value in the current scope? 如果我理解正确,你想要一个简写来在当前范围内打印变量名及其值吗? This is in general impossible without using the interpreters trace function or sys._getframe , which should in general only be used if you know what you're doing. 如果不使用解释器跟踪功能或sys._getframe ,这通常是不可能的,一般只有在你知道自己在做什么的情况下才能使用它。 The reason for this is that the print function has no other way of getting the locals from the calling scope: 原因是print函数没有其他方法可以从调用范围获取本地:

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

What you CAN do without these is explicitly pass the locals to a function like this: 没有这些你可以做什么明确地将本地传递给这样的函数:

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

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

EDIT: 编辑:

See the answer by catchemifyoutry for a solution using the inspect module (which internally uses sys._getframe). 请参阅catchemifyoutry的答案,了解使用inspect模块(内部使用sys._getframe)的解决方案。 For completeness a solution using the trace function directly - useful if you're using python 2.0 and inspect isn't available ;) 为了完整性,直接使用跟踪函数的解决方案 - 如果您使用的是python 2.0并且检查不可用;)

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

Save it in a module and use like this: 将其保存在模块中并使用如下:

from modulenamehere import enableTrace, printv

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

used a global variable to achieve this, func.__globals__.keys() contains all the variables passed to func , so I filtered out the name startin with __ and stored them in a list. 使用全局变量来实现这一点, func.__globals__.keys()包含传递给func所有变量,所以我用__过滤掉了名称startin并将它们存储在列表中。 with every call to func() the func.__globals__.keys() gets updated with the new variable name,so compare the new varn with the older glo results in the new variable that was just added. 每次调用func()func.__globals__.keys()都会使用新的变量名更新,因此将新的varn与刚刚添加的新变量中的旧的glo结果进行比较。

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[:]

output: 输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM