【问题标题】:How to write a function to return the variable name?如何编写一个函数来返回变量名?
【发布时间】:2012-08-30 02:15:38
【问题描述】:

我想要一个可以像 str 这样返回变量/对象名称的函数:

def get_variable_name (input_variable):
    ## some codes

>>get_variable_name(a)
'a'

>>get_variable_name(mylist)
'mylist'

它看起来很傻,但我需要该函数来构造关于变量的表达式,以便稍后在“exec()”中使用。有人可以帮忙写一下“get_variable_name”吗?

【问题讨论】:

  • 远远比你想象的要多。
  • 你为什么要这样做?我几乎可以肯定有更好的方法来做你想做的事(我的意思是除了你给出的非常简短的解释)
  • 根本问题是多个名称可以指向同一个对象。
  • 等等,你想得到一个函数参数的名字以便你可以在exec中使用它吗?那么,几乎可以肯定你已经走错了两个弯。这可能是XY problem 的一个示例,在该示例中,您不是寻求帮助来实现您的目标,而是寻求帮助以实施您不太实用的解决方案。
  • 感谢大家的富有成效的回答。我想我有解决问题的线索。

标签: python


【解决方案1】:

我现在已经在 SO 上多次看到此类问题的一些变体。答案是不要在您需要名称和对象之间的关联时,学习使用dict您稍后会为此感谢自己。

为了回答“我的代码如何发现对象的名称?”这个问题,这里是来自 Fredrik Lundh 的a quote(在 comp.lang.python 上):

与您在门廊上找到的那只猫的名字相同: 猫(物体)本身不能告诉你它的名字,它也不 真的很在乎——所以找出它叫什么的唯一方法就是问 你所有的邻居(命名空间)如果是他们的猫(对象)......

……如果您发现它有很多名字,请不要感到惊讶, 或者根本没有名字!


注意:技术上可以获取绑定到对象的名称列表,至少在 CPython 实现中是这样。如果您有兴趣看到演示,请参阅我的答案中显示的inspect 模块的用法:

Can an object inspect the name of the variable it's been assigned to?

这种技术应该只用在一些疯狂的调试会话中,不要在你的设计中使用这样的东西。

【讨论】:

  • 请注意,即使该链接也会为您提供对象名称s(复数)的列表。对象的“ 名称”实际上并不存在。
【解决方案2】:

一般来说这是不可能的。当您将某些东西传递给函数时,您传递的是对象,而不是名称。同一个对象可以有多个名称或没有名称。如果你调用get_variable_name(37),函数应该做什么?您应该考虑一下为什么要这样做,并尝试找到另一种方法来完成您的实际任务。

编辑:如果您希望get_variable_name(37) 返回 37,那么如果您先执行 a=37,然后执行 get_variable_name(a),那也将返回 37。一旦进入函数,它就无法知道对象的 "名字”在外面。

【讨论】:

  • 我不确定任何事情都是“不可能的”,但那说这将是非常困难和骇人听闻的并且容易损坏
  • 我不需要值,我只需要告诉变量名称的str输入到函数中。
  • 我希望 Python 为该对象提供内置的“objname”。我找不到那个。我只是希望这个功能为我的应用程序添加一些动态。即,我将生成一个关于变量的“str_statement”,并使用“exec(str_statement)”来完成这项工作。我知道这是一个坏习惯,但它是直觉和快速完成工作。 (我为自己构建应用程序,没有安全问题)
  • 您可以在父框架中挖掘名称,但这是完全错误的,除非他出于调试目的需要它...
  • 不要为此使用exec,也不要去找代号。学习使用dict,以防您需要名称和对象之间的一些对应关系,它会更直观并快速完成工作!
【解决方案3】:
def getvariablename(vara):
    for k in globals():
        if globals()[k] == vara:
                  return k
     return str(vara)

在某些情况下可能会起作用...但很容易损坏...而且我基本上永远不会在任何类型的生产代码中使用它...

基本上我想不出任何好的理由这样做......大约有一百万不这样做

【讨论】:

  • 非常方便的解决方案。 +1
【解决方案4】:

这是一个好的开始,根据 Python 版本和运行时,您可能需要稍作调整。打个断点,花点时间了解一下inspect.currentframe()的结构

import inspect

def vprint(v):
    v_name = inspect.currentframe().f_back.f_code.co_names[3]
    print(f"{v_name} ==> {v}")

if __name__ == '__main__':
    x = 15
    vprint(x)

会产生

x ==> 15

【讨论】:

    【解决方案5】:

    如果您只想返回根据用户输入选择的变量的名称...以便他们可以跟踪他们的输入,请在代码中添加一个变量名称,因为他们做出选择除了从他们生成的值之外选择。例如:

    temp = raw_input('Do you want a hot drink?  Type yes or no. ')
    size = raw_input('Do you want a large drink? Type yes or no. ')
    if temp and size == 'yes':
        drink = HL
        name = 'Large cafe au lait'
    if temp and size != 'yes':
        drink = CS
        name = 'Small ice coffee'
    print 'You ordered a ', name, '.'
    

    乔丹

    【讨论】:

    • 根据用户输入返回变量名以提供交互式反馈。
    【解决方案6】:

    如果您要在 exec() 中使用的语句是这样的

    a = ["ddd","dfd","444"]
    

    然后做这样的事情

    exec('b = a = ["ddd","dfd","444"]')
    

    现在您可以在代码中使用“b”来处理“a”。

    【讨论】:

      【解决方案7】:

      也许您可以使用 traceback.extract_stack() 获取调用堆栈,然后从条目中提取变量名称?

      def getVarName(a):
          stack = extract_stack()
          print(stack.pop(-2)[3])
      
      bob = 5
      getVarName(bob);
      

      输出:

      getVarName(bob)
      

      【讨论】:

        猜你喜欢
        • 2019-10-05
        • 2020-07-31
        • 2021-05-13
        • 2012-12-25
        • 2023-01-05
        • 1970-01-01
        • 1970-01-01
        • 2020-02-16
        • 2021-12-28
        相关资源
        最近更新 更多