我可以在Python中打印原始变量的名称吗?

时间:2009-02-13 06:30:06

标签: python variables

我有枚举并使用myEnum.SomeNameAmyEnum.SomeNameB等变量。当我从函数返回其中一个变量时,我可以打印它们的名称(例如myEnum.SomeNameA)而不是他们返回的价值?

12 个答案:

答案 0 :(得分:32)

简答:不。

答案很长:对于一些使用追踪,检查等的丑陋黑客来说这是可能的,但通常不建议用于生产代码。例如,见:

也许您可以使用变通方法将值转换回名称/表示字符串。如果您发布更多示例代码和详细信息,我们可能会提供更深入的帮助。

答案 1 :(得分:26)

没有唯一或原始的变量名称 http://www.amk.ca/quotations/python-quotes/page-8

  

就像你得到你在门廊上找到的那只猫的名字一样:猫(物体)本身不能告诉你它的名字,它并不真正关心 - 所以唯一的方法是找出它是什么被调用的是询问所有邻居(名称空间)是否是他们的猫(对象)......

     

....如果您发现它被许多名字所知,或者根本没有名字,请不要感到惊讶!

     

Fredrik Lundh,2000年11月3日,在回答“当我有PyObject *时如何从C ++获取变量的名称?”这个问题时<?strong>

答案 2 :(得分:22)

要添加到@Jay's answer,有些概念......

Python“变量”只是对值的引用。每个值占用给定的内存位置(请参阅id()

>>> id(1)
10052552

>>> sys.getrefcount(1)
569

根据以上所述,您可能会注意到值“1”出现在存储器位置10052552处。在此解释器实例中,它被称为569次。

>>> MYVAR = 1
>>> sys.getrefcount(1)
570

现在,请注意,因为另一个名称绑定到此值,引用计数增加了一个。

基于这些事实,判断单个变量名称指向某个值是不现实/可能的。

我认为解决问题的最佳方法是将枚举引用中的映射和函数添加回字符串名称。

myEnum.get_name(myEnum.SomeNameA) 

如果您想要示例代码,请发表评论。

答案 3 :(得分:6)

只需使用您要打印的文本作为枚举的值,如

class MyEnum (object):
    valueA = "valueA"
    valueB = "valueB"

比较字符串的身份在Python中几乎与比较整数值一样有效(这是因为字符串是不可变的,因为它具有哈希值)

当然,首先有更简单的方法来创建枚举:

class Enum (object):
    def __init__(self, *values):
        for v in values:
            self.__dict__[v] = v

然后,创建这样的枚举:

MyEnum = Enum("valueA", "valueB")

以与上述相同的方式访问:

MyEnum.valueA

答案 4 :(得分:3)

这个问题有两个答案:

Can you do it?  -- Yes (in most cases)
Is it worth it? -- No  (in most cases)

怎么做:

这取决于枚举的实现。例如:

class Enum:
    A = 1
    B = 2

如果您知道enums类对象并且所有它们都是名称(或至少是唯一的前缀),那么是否有100个名称引用您要查找的名称的整数无关紧要类

对于上面示例as @batbrat suggested,您可以使用namestr()检查“Enum.__dict__”:

 >>> getEnum = lambda: Enum.A
 >>> namestr(getEnum(), Enum.__dict__)
 >>> ['A']

在这种情况下,您甚至不必知道所有枚举名称。如果枚举实现不同,那么您可能需要使用不同的hack。在大多数情况下会有一些解决方案,例如,请参阅@Jay's answer。但这并不重要因为......

值得吗?

  • 有些枚举实现可能需要丑陋,复杂且最终不可靠的黑客来实现namestr()

  • 枚举类可以自行返回答案(请参阅@David's@Ber's@gahooa's答案。

  • 作为@Ber pointed out,Python中没有内置的Enum和switch语句(请参阅PEP-0275PEP-3103)。值得研究没有枚举的解决方案。

答案 5 :(得分:2)

您可以将规范名称存储为实例的属性,然后将其分配给具有相同名称的变量。这可能有效:

class MyEnum(object):
    def __new__(cls, name):
        try:
            return getattr(MyEnum, name)
        except AttributeError:
            e = super(MyEnum, cls).__new__(cls)
            e.name = name
            setattr(MyEnum, name, e)
            return e

无论如何,这不是特别“Pythonic”的事情。

答案 6 :(得分:2)

第二个想法:

由于Python不提供本机Enum类型,因此您不应该要求使用,而是使用其他更强大的构造来构建程序。否则,下一步将始终是“为什么Python没有switch ...:语句,以及如何最好地模仿它?”

由于枚举通常用于定义某种状态,因此更好的方法是: 创建一个基类,用于定义属于某个状态的所有抽象属性,属性和方法。然后,对于每个状态,派生一个实现此状态的特定行为的子类。然后,您可以传递这些类(或可能是其实例)来处理状态及其行为。

如果你使用类而不是实例(Python的“单身”方式),你可以通过if current_state is StateA:检查任何给定的状态(而不是它应该是必要的)(注意is而不是==)而不是比较整数值的性能损失。

当然,您可以定义name属性和__str__()方法来访问和打印州名称。

答案 7 :(得分:0)

据我所知,这需要一些反省。您可以尝试使用检查模块。

在此之前您可能想要尝试一些简单的事情:

        
  1. 这不是应该使用的确切代码。在打印之前,您必须从__dict__中检索变量名称。         
    print myEnum.__dict__
            
        
  2.     
  3.         如果要从函数内部打印变量名,可以尝试         函数 - vars(),locals()和globals()。         
    编辑
            我只是注意到这不是你想要的。在那种情况下添加一个         字典和功能可能有效     
  4.     
  5.         您可能想要打印枚举类的__dict__。     
  6. 所有这一切,Python中没有标准的枚举。了解你是如何创建它们会有所帮助。

    再想一想,您可以将变量保存为枚举中的字典,由变量名称键入,并提供枚举方法以查找正确的变量并打印其名称。这个解决方案(保持字典)很糟糕,因为变量值不一定是唯一的。

    修改
    这个问题并非无足轻重,因此您可能希望使用久经考验的解决方案。恕我直言,如果可以的话,你最好避免这种情况。

答案 8 :(得分:0)

Erlang有一个名为“atoms”的概念 - 它们类似于字符串常量或枚举。考虑使用字符串常量作为枚举的值 - 与枚举的名称相同。

答案 9 :(得分:0)

import inspect

def printVariableName(abc):
    newvar=inspect.stack()[1][4][0]
    print(newvar.split("(")[1].split(")")[0])

noob=10
printVariableName(noob)

输出:

noob

答案 10 :(得分:0)

Python 3.8为此添加了一个新的,也许是一个的更好的解决方案:

my_nice_variable_name = 'test'
print(f'{my_nice_variable_name=}')

# Output:
# my_nice_variable_name='test'

在这里您可以使用字符串输出。仍然不建议这样做,但可能比其他方法要好一些。

答案 11 :(得分:0)

我知道这是一个古老的问题,但是使用f strings 可能

my_variable = some_object
f'{my_variable=}'.split('=', 1)[0]

这将打印 'my_variable'