globals()返回一个表示模块名称空间的字典(名称空间不是这个字典,后者只表示它)class A(object):
def get_instance_name(self):
for name,ob in globals().iteritems():
if ob is self:
return name
obj = A()
print obj.get_instance_name()
blah = A()
print blah.get_instance_name()
tu = (obj,blah)
print [x.get_instance_name() for x in tu]
结果
^{pr2}$
一。在
编辑
考虑到这些评论,我编写了以下新代码:class A(object):
def rondo(self,nameinst,namespace,li,s,seen):
for namea,a in namespace.iteritems():
if a is self:
li.append(nameinst+s+namea)
if namea=='__builtins__':
#this condition prevents the execution to go
# in the following section elif, so that self
# isn't searched among the cascading attributes
# of the builtin objects and the attributes.
# This is to avoid to explore all the big tree
# of builtin objects and their cascading attributes.
# It supposes that every builtin object has not
# received the instance, of which the names are
# searched, as a new attribute. This makes sense.
for bn,b in __builtins__.__dict__.iteritems():
if b is self:
li.append(nameinst+'-'+b)
elif hasattr(a,'__dict__') \
and not any(n+s+namea in seen for n in seen)\
and not any(n+s+namea in li for n in li):
seen.append(nameinst+s+namea)
self.rondo(nameinst+s+namea,a.__dict__,li,'.')
else:
seen.append(nameinst+s+namea)
def get_instance_name(self):
li = []
seen = []
self.rondo('',globals(),li,'')
return li if li else None
包括以下内容bumbum = A()
blah = A()
print "bumbum's names:\n",bumbum.get_instance_name()
print "\nmap(lambda y:y.get_instance_name(), (bumbum,blah) :\n",map(lambda y:y.get_instance_name(), (bumbum,blah))
print "\n[y.get_instance_name() for y in (bumbum,blah)] :\n",[y.get_instance_name() for y in (bumbum,blah)]
结果是bumbum's names:
['bumbum']
map(lambda y:y.get_instance_name(), (bumbum,blah) :
[['bumbum'], ['blah']]
[y.get_instance_name() for y in (bumbum,blah)] :
[['bumbum', 'y'], ['blah', 'y']]
第二个列表理解说明函数get_instance_name()必须小心使用。在list comp中,标识符y依次分配给(bumbum,blah)的每个元素,然后finction将其作为实例的名称找到!在
一。在
现在,更复杂的情况是:ahah = A() # ahah : first name for this instance
class B(object):
pass
bobo = B()
bobo.x = ahah # bobo.x : second name for ahah
jupiter = bobo.x # jupiter : third name for ahah
class C(object):
def __init__(self):
self.azerty = jupiter # fourth name for ahah
ccc = C()
kkk = ccc.azerty # kkk : fifth name for ahah
bobo.x.inxnum = 1005
bobo.x.inxwhat = kkk # bobo.x.inxwhat : fifth name for ahah
# Since bobo.x is instance ahah, this instruction also
# creates attribute inxwhat in ahah instance's __dict__ .
# Consequently, instance ahah having already 5 names,
# this instruction adds 5 additional names, each one
# ending with .inxwhat
# By the way, this kkk being ahah itself, it results that ahah
# is the value of its own attribute inxwhat.
print ahah.get_instance_name()
结果['bobo.x', 'bobo.x.inxwhat',
'ahah', 'ahah.inxwhat',
'jupiter', 'jupiter.inxwhat',
'kkk', 'kkk.inxwhat',
'ccc.azerty', 'ccc.azerty.inxwhat']
我同意判断这个解有点重,如果一个编码器认为他需要这么重的函数,可能是因为算法不是最优的。但是我发现有趣的是,在Python中实现这一点是可能的,尽管它看起来并不明显。在
我说的是重的,不是粗的,顺便说一句,我不觉得它很粗糙。在