从函数外部返回变量名称,作为python函数中的字符串 [英] return variable name from outside of function, as string inside python function
问题描述
所以我创建了一个函数,将一个动作(在这种情况下,将数组与一个正弦曲线的点乘乘,但这对我的问题无关紧要)应用于一个数组。
现在我创建了另一个函数,我想用它创建一个字符串
的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屋!