Rob的答案(上面得票最高)是正确的。我想补充一点,在某些情况下使用ID是有用的,因为它允许比较对象并找到哪些对象引用了您的对象。
后者通常有助于您调试奇怪的错误,其中可变对象作为参数传递给类,并被分配给类中的局部变量。如果改变这些对象,将会改变类中的变量。这表现为多个事物同时发生变化的奇怪行为。
最近我在一个Python/Tkinter应用程序中遇到了这个问题,在一个文本输入字段中编辑文本会随着我的输入而更改另一个文本输入字段中的文本 :)
以下是一个示例,说明如何使用函数id()来跟踪引用的位置。毫无疑问,这不是覆盖所有可能情况的解决方案,但您可以了解到大致思路。再次强调,ID在后台使用,用户看不到它们:
class democlass:
classvar = 24
def __init__(self, var):
self.instancevar1 = var
self.instancevar2 = 42
def whoreferencesmylocalvars(self, fromwhere):
return {__l__: {__g__
for __g__ in fromwhere
if not callable(__g__) and id(eval(__g__)) == id(getattr(self,__l__))
}
for __l__ in dir(self)
if not callable(getattr(self, __l__)) and __l__[-1] != '_'
}
def whoreferencesthisclassinstance(self, fromwhere):
return {__g__
for __g__ in fromwhere
if not callable(__g__) and id(eval(__g__)) == id(self)
}
a = [1,2,3,4]
b = a
c = b
democlassinstance = democlass(a)
d = democlassinstance
e = d
f = democlassinstance.classvar
g = democlassinstance.instancevar2
print( 'My class instance is of', type(democlassinstance), 'type.')
print( 'My instance vars are referenced by:', democlassinstance.whoreferencesmylocalvars(globals()) )
print( 'My class instance is referenced by:', democlassinstance.whoreferencesthisclassinstance(globals()) )
输出:
My class instance is of <class '__main__.democlass'> type.
My instance vars are referenced by: {'instancevar2': {'g'}, 'classvar': {'f'}, 'instancevar1': {'a', 'c', 'b'}}
My class instance is referenced by: {'e', 'd', 'democlassinstance'}
在变量名中使用下划线是为了防止名称冲突。函数使用 "fromwhere" 参数,这样您就可以让它们知道从哪里开始搜索引用。该参数由列出给定命名空间中所有名称的函数填充。Globals() 是其中之一。