您可以从类中获取实例变量名称吗? [复制]

Posted

技术标签:

【中文标题】您可以从类中获取实例变量名称吗? [复制]【英文标题】:Can you get the instance variable name from a class? [duplicate] 【发布时间】:2015-08-23 05:00:57 【问题描述】:

我知道你不应该在程序中使用变量名,但我使用的只是为了调试目的,并希望将变量名传达给用户以提高可读性。

我有一个这样的文件:

class MyClass(object):
    def __init__(self):
        pass

    def foo(msg=""):
        debug("Called from the %s instance.") #quazi-print function that only prints when a DEBUG variable is True.
        print(msg)

m = MyClass()
m.foo("Test")

我想从类本身中检索m 实例变量名称。虽然这只是一个示例文件,但我使用它来向用户传达已在实例变量中的某个属性处创建了一个原始套接字,并希望显示它在哪里(即New socket at m.socket

这对 Python 可行吗?

【问题讨论】:

即使出于调试目的,如果用户对对象有多个引用,也会感到困惑。最好有一个明确的名称(可能由用户在为特定对象打开调试时指定)。 这有点可行,但您必须搜索所有可能已定义m 的命名空间,以查找它的绑定。 print(MyClass())中的实例名称是什么 这已经很晚了,但我刚刚从谷歌上看到了这个:这实际上是 not 重复的,因为上面提到的答案返回了 class(这里是"MyClass")。我们在这里寻找的是 variable 的名称,它指的是类的特定实例(这里:'m')。任何人都可以删除“重复”标记?任何人都知道答案(还没有找到)。 【参考方案1】:

您可以查看实例的 globals 字典并找到以自身为值的项目。

class Foo(object):
    def bar(self):
        return [k for k,v in globals().items() if v is self]
    def bah(self):
        d = v:k for k,v in globals().items()
        return d[self]

f = Foo()
g = Foo()

print f.bar(), g.bar()
print f.bah(), g.bah()

>>> 
['f'] ['g']
f g
>>> 

【讨论】:

所以,如果变量不是全局变量,这将不起作用,对吗?有什么办法可以避免吗?如果它不是全局的,这会引发错误吗? @Goodies,实例名称应始终在其外部范围内,这是 globals() 产生的。 -至少我认为,也许有人会插话。 @Goodies 嗯,如果你在函数中创建实例,它不在globals【参考方案2】:

如果您不介意程序在此时退出,这是一种非常愚蠢的方法:将此行添加到 foo():

print undefined_variable

当你到达那里时,你会得到这样的堆栈跟踪:

Traceback (most recent call last): File "test.py", line 15, in <module> m.foo("Test") File "test.py", line 11, in foo print undefined_variable NameError: global name 'undefined_variable' is not defined

...它告诉你调用它的变量的名称是'm' :)

(您可能可以使用traceback 模块执行类似的操作,而无需终止程序。我尝试了几种方法,但未能将m.foo() 行包含在输出。)

【讨论】:

我不赞成,因为它很有用;我赞成,因为它很聪明。 你应该写raise Exception()而不是打印。 是的,我尝试了try ... raise ... except: print (various things from the traceback module),但我找不到任何包含m.foo() 行的回溯对象。请注意,我并没有很努力——很可能有一个:)【参考方案3】:

是的。要获取类的所有成员,可以使用内置关键字“dir”。它将列出您的类中的所有方法和变量。如果您使用正确的命名转换,您应该能够分辨出哪些名称是变量,哪些是方法。 Dir 返回一个字符串列表。

class Man():
    def __init__(self):
        self.name = "Bob"
        self.color = "White"
m = Man()
    print dir(m)

这将打印出来:

['doc', 'init', 'module', 'color', 'name']

color和name不是这个类的实例变量名吗?

【讨论】:

这并不能回答问题——我们想得到一个包含'm'的字符串

以上是关于您可以从类中获取实例变量名称吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥从类和实例中获取属性的查找过程不同?

导出的类中可以有私有成员吗? [复制]

为啥从类中访问类变量需要“自我”。在 Python 中? [复制]

JAVA中类中的实例方法可以操作类变量(static变量)吗?类方法(static方法)可以操作实例变量吗?

实例变量作为其他实例变量的函数

类别可以访问它扩展的类中定义的实例变量吗?