stevenha给出了一个很好的答案。但是,如果你真的想要在命名空间字典中查找,你可以像这样获取特定作用域/命名空间中给定值的所有名称:
def foo1():
x = 5
y = 4
z = x
print names_of1(x, locals())
def names_of1(var, callers_namespace):
return [name for (name, value) in callers_namespace.iteritems() if var is value]
foo1()
如果你正在使用支持堆栈帧的Python(大多数都支持,包括CPython),则不需要将本地字典传递到names_of
函数中;该函数可以从其调用者的帧本身检索该字典:
def foo2():
xx = object()
yy = object()
zz = xx
print names_of2(xx)
def names_of2(var):
import inspect
callers_namespace = inspect.currentframe().f_back.f_locals
return [name for (name, value) in callers_namespace.iteritems() if var is value]
foo2()
如果您正在使用可以分配名称属性的值类型,则可以为其命名,然后使用该名称:
class SomeClass(object):
pass
obj = SomeClass()
obj.name = 'obj'
class NamedInt(int):
__slots__ = ['name']
x = NamedInt(321)
x.name = 'x'
如果你正在使用类属性,并且希望它们知道自己的名称(描述符是显而易见的用例),那么你可以像 Django ORM 和 SQLAlchemy 声明式表定义中所做的那样,使用元类编程的酷技巧。
class AutonamingType(type):
def __init__(cls, name, bases, attrs):
for (attrname, attrvalue) in attrs.iteritems():
if getattr(attrvalue, '__autoname__', False):
attrvalue.name = attrname
super(AutonamingType,cls).__init__(name, bases, attrs)
class NamedDescriptor(object):
__autoname__ = True
name = None
def __get__(self, instance, instance_type):
return self.name
class Foo(object):
__metaclass__ = AutonamingType
bar = NamedDescriptor()
baaz = NamedDescriptor()
lilfoo = Foo()
print lilfoo.bar
print lilfoo.baaz