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

我有枚举和使用像myEnum.SomeNameAmyEnum.SomeNameB等variables。当我从函数返回这些variables之一,我可以打印他们的名字(如myEnum.SomeNameA ),而不是他们返回的值?

简短的回答:不。

很长的回答:这是可能的一些丑陋的黑客使用追溯,检查等,但它通常可能不build议生产代码。 例如见:

也许你可以使用一个解决方法将值转换回名称/表示string。 如果你张贴一些更多的示例代码和细节,你可能会提供更深入的帮助。

没有独特的或原始的variables名称http://www.amk.ca/quotations/python-quotes/page-8

就像你在门廊find那只猫的名字一样:猫(物体)本身不能告诉你它的名字,它并不真正在意 – 所以唯一的办法就是找出它叫做什么的问你所有的邻居(名字空间)是否是他们的猫(对象)…

….如果你会发现它是众所周知的名字,或根本没有名字,不要感到惊讶!

Fredrik Lundh,2000年11月3日,回答“当我有PyObject *时,如何从C ++获取variables的名字?

要添加@周杰伦的答案 ,一些概念…

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

 >>> id(1) 10052552 >>> sys.getrefcount(1) 569 

从上面,你可能会注意到值“1”出现在内存位置10052552.在解释器的这种情况下,它被称为569次。

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

现在看到,因为另一个名字被绑定到这个值,引用计数增加了一个。

基于这些事实,告诉单个variables名称指向哪个值是不现实/可能的。

我认为解决你的问题的最好办法是添加一个映射和函数到你的枚举引用返回一个string名称。

 myEnum.get_name(myEnum.SomeNameA) 

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

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

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

比较string的身份在Python中几乎和整数值一样高效(这是因为string是不可变的,因为它有散列值)

当然有更简单的方法来创build枚举:

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

然后,像这样创build你的枚举:

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

ans的访问方式与上面相同:

 MyEnum.valueA 

这个问题有两个答案:

你可以做到吗?  - 是的(在大多数情况下)
这值得么?  - 不(在大多数情况下)

怎么做:

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

 class Enum: A = 1 B = 2 

如果知道枚举类对象,并且它们是该类中的所有名称(或至less是唯一前缀),那么是否有100个名称是指您想要查找的名称的整数。

对于上面的例子@batbratbuild议你可以使用namestr()检查' Enum.__dict__ ':

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

在这种情况下,你甚至不需要知道所有的枚举名称。 如果枚举实现不同,那么你可能需要使用不同的黑客。 在大多数情况下会有一些解决scheme,例如,看@ Jay的答案 。 但是没关系,因为..

这值得么?

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

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

  • 正如@Ber指出 ,Python中没有内置的Enum和switch语句(参见PEP-0275 , PEP-3103 )。 没有枚举值得研究解决scheme。

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

 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”的事情。

再想一想:

由于Python不提供原生的Enumtypes,所以你不应该要求一个,而是使用其他更强大的构造来构build你的程序。 否则,下一步将总是“为什么Python没有switch ...:语句,我如何最好地模拟它?”

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

如果你使用类而不是实例(Python的“单例”方式),你可以通过if current_state is StateA:来简单地检查给定的状态(不是必须的) if current_state is StateA:注意is而不是== )比较整数值没有性能损失。

当然,你可以定义一个name属性和一个__str__()方法来访问和打印状态的名字。

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

有几个简单的事情你可能想尝试之前:

  1. 这不是应该使用的确切代码。 打印之前,必须从__dict__中检索variables名称。
    打印myEnum .__ dict__
            
  2. 如果你想从函数内部打印variables名,你可以尝试函数–Vars(),locals()和globals()。
    编辑
    我只是注意到,这不是你想要的。 在这种情况下,添加一个字典和一个函数可能会起作用
  3. 你可能想打印你的枚举类的__dict__。

总之,Python中没有标准的枚举。 这将有助于知道你是如何创造他们。

第二个想法是,可以将variables作为字典保存在枚举中,用variables名作为键,并提供一个枚举方法来查找正确的variables并打印其名称。 这个解决scheme(保留一个字典)是不好的,因为variables值不一定是唯一的。

编辑
问题不是微不足道的,所以你可能想要使用一个久经考验的解决scheme。 恕我直言,如果可以的话,你最好避免这种情况。

Erlang有一个叫做“atoms”的概念 – 它们类似于string常量或者枚举。 考虑使用一个string常量作为你的枚举的值 – 与枚举的名字相同。