从函数外部返回变量名称,作为python函数中的字符串 [英] return variable name from outside of function, as string inside python function

查看:328
本文介绍了从函数外部返回变量名称,作为python函数中的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我创建了一个函数,将一个动作(在这种情况下,将数组与一个正弦曲线的点乘乘,但这对我的问题无关紧要)应用于一个数组。



现在我创建了另一个函数,我想用它创建一个字符串的python代码,以便稍后多次应用第一个函数。第二个函数的输入可以是字符串数组,这样我就可以使用第二个函数它自己的输出也是如此,如果需要的话。我在字符串中获取变量名的方法在函数外部工作。

输入:

  var = (var)== str:
var_name = var
else:
var_name = [k for k,v in locals()。items()if v is var] [0]

var_name
<



输出: 'var'

所以这里 var 是提供给函数的变量(数组或字符串),在这种情况下是一个数组。 if语句很好地返回了它的名字。



然而,当我在我的函数中使用这个函数时,无论我给它什么输入,它似乎都会查找 var 在locals()中。不知何故,它不会从函数输入中使用 var

定义:

  def functionTWO(var,listoflistsofargs = None):
if(var)== str:
var_name = var
else
var_name = [k for k,v in locals()。items()if v is var] [0]
if listoflistsofargs == None:
return var_name
如果我== 0:
command.append('functionONE(')
command.append('($)')
(len(listoflistsofargs) var_name)
command.append(',%。17f,%.17f)'%tuple(listoflistsofargs [i]))
else:
command.insert(0,'functionONE(' )
command.append(',%。17f,%.17f)'%tuple(listoflistsofargs [i]))$ b $'.join(command)
command [0] = var_name +'+'+ command [0]
return''.join(command)

输入:

  somearray = np.array([[1,2,3],[1,2,3 ],[1,2,3]])
args = [[1,3],[6,5]]
command = functionTWO(somearray,args)
命令

输出:

 NameError:name'var'未定义

想要的输出:

 'functionONE(functionONE(somearray,1,3),6,5)'

为什么从函数输入取得 listoflistsofargs code> var 不是?我在 functionTWO 的定义中的listcomprehension中指定了 var 。通常,当我使用列表推导与功能输入,它工作正常。有人知道为什么这里不是这种情况吗?提前感谢您!



编辑:所以我想答案是不要。 Marcin实现的类看起来更清晰,大小与代码量相同。太糟糕了,我不能让它在一个函数内部工作。对于使用变量名作为字符串的其他 donts (实际上是其他想法),有问题,我得到了上面列表中对变量名的理解。

你不能将一个变量作为字符串*传递,你不应该这样做。



如果您想在函数之间传递一个值,常规方法是将其作为参数传递,并作为返回值传递。



如果这样做不方便,通常的解决方案是一个对象:定义一个类,它携带共享变量和作用于该变量的方法。



如果您需要创建命令对象,那么以结构化的方式更好。例如,如果你想传递一个函数和参数,你可以直接传递函数对象和参数到一个元组中:

  return(functionONE,somearray,1,3)

command = foo()
command [0](* command [1:] )

如果你想在命令中嵌入这样的命令,你可能想要把它包装起来一个类,所以你可以递归地评估参数。实际上,这里有一个小小的评估者:

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ def $ __init __(self,func = None ,params = None):
self.func = func
self.params = params
$ b $ def eval(self,alternativeparams = None):
如果alternativeparams不是None:
params = alternativeparams
else:
params = self.params

如果params不是None:
evaluateparams =(item()if callable (item)其他项目在params中)
else:evaluateparams = None

如果func不是None:
return self.func(*(evaluateparams or()))
else:return evaluateparams
def __call __(self,* params):
return self.eval(params if params else None)

虽然有些黑客可以将引用传递给局部变量,但这些并不是一个好主意,因为您最终会创建你自己的一半的对象系统,这是更难以理解。

* 这是因为一个变量有一个名称(这是一个字符串)和一个将名称映射到字符串的上下文。所以,至少需要传递一个元组来真正传递一个变量。


So I have created a function that applies an action (in this case point wise multiplication of an array with a sinusoid, but that does not matter for my question) to an array.

Now I have created another function with which I want to create a string of python code to apply the first function multiple times later-on. The input of the second function can be either a string or an array, so that I can use the second function on its own output as well, if need be. My method of getting the variable name in a string works outside of the function.

Input :

var = np.array([[1,3],[2,4]]) # or sometimes var = 'a string'

if type(var)==str:
    var_name = var
else:
    var_name = [ k for k,v in locals().items() if v is var][0]

var_name

Output :

'var'

So here var is the variable (either array or string) supplied to the function, in this case an array. The if statement nicely returns me its name.

However when I use this inside my function, no matter what input I give it, it actually seems to look for var in locals(). Somehow it does not take var from the function input.

Definition :

def functionTWO(var, listoflistsofargs=None):
    if type(var)==str:
        var_name = var
    else:
        var_name = [ k for k,v in locals().items() if v is var][0]
    if listoflistsofargs==None:
        return var_name
    command = []
    for i in range(len(listoflistsofargs)):
        if i==0:
            command.append('functionONE(')
            command.append(var_name)
            command.append(',%.17f, %.17f)' % tuple(listoflistsofargs[i]))
        else:
            command.insert(0,'functionONE(')
            command.append(',%.17f, %.17f)' % tuple(listoflistsofargs[i]))
    ''.join(command)
    command[0] = var_name + ' + ' + command[0]
    return ''.join(command)

Input :

somearray = np.array([[1,2,3],[1,2,3],[1,2,3]])
args = [[1,3],[6,5]]
command = functionTWO(somearray, args)
command

Output :

NameError: name 'var' is not defined

Wanted output :

'functionONE(functionONE(somearray, 1, 3), 6, 5)'

Why is listoflistsofargs taken from the function input and var not? I specify var in the listcomprehension in the definition of functionTWO. Normally when I use list comprehensions with function inputs it works fine. Does anybody know why this isnt the case here? Thank you in advance!

EDIT : So I guess the answer is dont. The implementation of classes by Marcin looks much cleaner and about the same order of amount of code. Too bad I couldnt get this to work inside a function. For other donts (actually other ideas) about using variable names as strings there is this question, where I got the above list comprehension for variable names.

解决方案

You cannot pass a variable as a string*, and you should not do so.

If you want to pass a value between functions, the normal way is to pass it in as a parameter, and out as a return value.

If that is inconvenient, the usual solution is an object: define a class which carries both the shared variable, and methods which act on the variable.

If you need to create command objects, it is much better to do so in a structured way. For example, if you want to pass a function, and parameters, you can literally just pass the function object and the parameters in a tuple:

def foo():
    return (functionONE,somearray,1,3)

command = foo()
command[0](*command[1:])

If you want to embed such commands within commands, you'll likely want to wrap that up with a class, so you can recursively evaluate the parameters. In fact, here's a little evaluator:

def evaluator(object):
    def __init__(self,func=None,params=None):
        self.func = func
        self.params = params

    def eval(self,alternativeparams=None):
        if alternativeparams is not None:
           params = alternativeparams
        else:
           params = self.params

        if params is not None:
           evaluatedparams = (item() if callable(item) else item for item in params)
        else: evaluatedparams = None

        if func is not None:
           return self.func(*(evaluatedparams or ()))
        else: return evaluatedparams
    def __call__(self, *params):
        return self.eval(params if params else None)

Although there are hacks by which you can pass references to local variables out of a function, these are not a great idea, because you end up creating your own half-baked object system which is more difficult to understand.

* This is because a variable has a name (which is a string) and a context, which maps names to strings. So, you need, at least to pass a tuple to truly pass a variable.

这篇关于从函数外部返回变量名称,作为python函数中的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆