Can I print original variable's name in Python?
我有枚举并使用
简短回答:不。
长话短说:这是有可能的一些丑陋的黑客使用回溯,检查等,但它通常不建议用于生产代码。例如,请参见:
- http://groups.google.com/group/comp.lang.python/msg/237DC92F3629DD9A?PLI=1
- http://aspn.activestate.com/aspn/mail/message/python-tutor/330294
也许您可以使用变通方法将值转换回名称/表示字符串。如果您发布更多的示例代码和您想要它的详细信息,也许我们可以提供更深入的帮助。
没有唯一或原始变量名这样的东西http://www.amk.ca/quotes/python-quotes/page-8
The same way as you get the name of that cat you found on your porch: the cat (object) itself cannot tell you its name, and it doesn't really care -- so the only way to find out what it's called is to ask all your neighbours (namespaces) if it's their cat (object)...
....and don't be surprised if you'll find that it's known by many names, or no name at all!
Fredrik Lundh, 3 Nov 2000, in answer to the question"How can I get the name of a variable from C++ when I have the PyObject*?"
为了增加@jay的答案,一些概念…
python"变量"只是对值的引用。每个值占用一个给定的内存位置(参见
1 2 3 4 5 | >>> id(1) 10052552 >>> sys.getrefcount(1) 569 |
从上面,您可能会注意到值"1"存在于内存位置10052552。在这个解释器实例中,它被引用了569次。
1 2 3 | >>> MYVAR = 1 >>> sys.getrefcount(1) 570 |
现在,请注意,因为这个值还绑定了另一个名称,所以引用计数增加了一个。
基于这些事实,判断单个变量名指向某个值是不现实的/不可能的。
我认为解决这个问题的最佳方法是将一个映射和函数添加到枚举引用中,再添加回一个字符串名称。
1 | myEnum.get_name(myEnum.SomeNameA) |
如果您想要示例代码,请发表评论。
只需使用要打印的文本作为枚举值,如
1 2 3 | class MyEnum (object): valueA ="valueA" valueB ="valueB" |
在python中,将字符串与标识进行比较的效率几乎与比较整数值的效率相同(这是因为字符串是不可变的,具有哈希值)。
当然,首先有一些更简单的方法来创建枚举:
1 2 3 4 | class Enum (object): def __init__(self, *values): for v in values: self.__dict__[v] = v |
然后,像这样创建枚举:
1 | MyEnum = Enum("valueA","valueB") |
ANS访问方式与上述相同:
1 | MyEnum.valueA |
对。
对于Enums,很容易:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | >>> from enum import Enum >>> class Type(Enum): ... AB, SBS, INTERLACED, SPLIT = range(4) ... >>> Type.AB <Type.AB: 0> >>> print(Type.AB) Type.AB >>> Type.AB.name 'AB' >>> Type.AB.value 0 >>> Type(0) <Type.AB: 0> |
一般来说,这可能是不明确的:
1 2 3 4 5 6 7 8 9 10 | >>> def varname(v): d = globals(); return [k for k in d if d[k] == v] ... >>> def varnameis(v): d = globals(); return [k for k in d if d[k] is v] ... >>> foo = {'a':'aap'} >>> bar = {'a':'aap'} >>> varname(foo) ['foo', 'bar'] >>> varnameis(foo) ['foo'] |
甚至误导:
1 2 3 4 5 6 7 8 9 10 | >>> foo ="A"; bar ="A" >>> varnameis("A") ['foo', 'bar'] >>> foo ="An immutable value."; bar ="An immutable value." >>> varnameis("An immutable value.") [] >>> foo ="An immutable value."; bar ="An immutable value."; varnameis("An immutable value.") ['foo', 'bar'] >>> import sys; sys.version '3.6.6 (v3.6.6:4cf1f54eb7, Jun 27 2018, 02:47:15) [MSC v.1900 32 bit (Intel)]' |
要在任何范围内搜索,请使用以下命令:
1 2 3 4 5 6 7 8 9 | >>> def varname(v, scope=None): d = globals() if not scope else vars(scope); return [k for k in d if d[k] == v] ... >>> import time >>> time.timezone -3600 >>> varname(-3600) [] >>> varname(-3600, time) ['timezone'] |
这个问题有两个答案:是和否。
1 2 | Can you do it? -- Yes (in most cases) Is it worth it? -- No (in most cases) |
如何做到这一点:
它取决于枚举的实现。例如:
1 2 3 | class Enum: A = 1 B = 2 |
不管是否有100个名称是指一个整数,如果你知道枚举类对象的名称,并且它们都是该类中的名称(或者至少是唯一的前缀),你都想找到这个整数。
对于上面的示例,如@batbrat建议您可以使用
1 2 3 | >>> getEnum = lambda: Enum.A >>> namestr(getEnum(), Enum.__dict__) >>> ['A'] |
在这种情况下,您甚至不必知道所有枚举名称。如果枚举的实现方式不同,那么您可能需要使用不同的hack。在大多数情况下都会有一些解决方案,例如,参见@jay's answer。但没关系,因为……
值得吗?一些枚举实现可能需要丑陋、复杂和最终不可靠的黑客来实现
namestr() 。枚举类可以自己返回答案(请参见@david's、@ber's、@gahooa's answers)。
正如@ber指出的那样,python中没有内置的枚举和switch语句(参见pep-0275、pep-3103)。在没有枚举的情况下研究解决方案是值得的。
第二个想法:
因为python不提供本机枚举类型,所以您不应该要求一个,而是使用其他更强大的构造来构建程序。否则,下一步将始终是"为什么Python没有
由于枚举通常用于定义某种状态,因此更好的方法是:创建一个基类,定义属于某个状态的所有抽象属性、属性和方法。然后,对于每个状态,派生一个子类来实现该状态的特定行为。然后您可以传递这些类(或其实例)来处理状态及其行为。
如果使用类而不是实例("singleton"的python方式),则可以简单地检查
当然,您可以定义一个
您可以将规范名称存储为实例的属性,然后将其分配给具有相同名称的变量。这可能有效:
1 2 3 4 5 6 7 8 9 | 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 |
无论如何,这不是一个特别的"Python"的事情要做。
Erlang有一个称为"原子"的概念——它们类似于字符串常量或枚举。考虑使用字符串常量作为枚举的值——与枚举的名称相同。
据我所知,这需要一些反省。您可以尝试使用检查模块。
在此之前,您可能需要尝试一些简单的方法:
1 | print myEnum.__dict__ |
编辑:
我只是注意到这不是你想要的。在这种情况下,添加听写和函数可以工作
尽管如此,python中没有标准的枚举。这将有助于了解您是如何创建它们的。
再想一想,您可以将变量作为字典保存在枚举中,通过变量名进行键控,并提供枚举方法来查找正确的变量并打印其名称。此解决方案(保留dict)不好,因为变量值不一定是唯一的。
编辑:
这个问题并不简单,所以您可能需要使用一个经过尝试和测试的解决方案。imho,如果可以的话,你最好避开这种情况。