MiscItems/2011-11-05

如何返回实例名称

起问

Yi Zhou [email protected]
发件人当地时间:         发送时间 14:37 (GMT-07:00)。发送地当前时间:上午2:13。 ✆
回复:      [email protected]
发送至:     "python-cn(华蟒用户组,CPyUG 邮件列表)" <[email protected]>
主题:      [CPyUG] 如何返回实例名称?

一个函数,有一个参数,现在需要返回这个参数的名字,怎么实现? 比如

   1 def function(arg):
   2    return arg.name
   3 
   4 asdfasdf={}
   5 function(asdfasdf)

我现在想让函数返回 'asdfasdf‘ 这个字符串,怎么写这个函数?

Musheng

Musheng [email protected]
发件人当地时间:         发送时间 20:57 (GMT+08:00)。发送地当前时间:下午5:17。 ✆

   1 import inspect
   2 
   3 def call_me(who,what=''):
   4    f=inspect.currentframe()
   5    cd=f.f_code
   6    print cd.co_varnames[:cd.co_argcount]
   7 
   8 
   9 if __name__=='__main__':
  10    call_me('python')

hongqn

 Qiangning Hong [email protected] 通过“googlegroups.com”
发件人当地时间:         发送时间 18:11 (GMT+08:00)。发送地当前时间:下午5:16。 ✆

gc

对象本身没有名字,只有名字绑定。一个对象可以绑定在多个名字上。

用 gc 模块可以得到对指定对象的所有引用,可以遍历这个引用找到可能的绑定在对象上的名字。

代码示例:

   1 import gc
   2 
   3 def get_possible_names(obj):
   4     names = set()
   5     for ref in gc.get_referrers(obj):
   6         if type(ref) is dict:
   7             names.update(k for k, v in ref.iteritems() if v is obj)
   8     return names
   9 
  10 asdfasdf = {}
  11 print get_possible_names(asdfasdf)
  12 
  13 # 输出
  14 set(['asdfasdf'])

不过话说回来,这种做法很不可靠,而且这个需求本身也很没有意义。

opcode

楼主想要的是获取一个作为函数参数对象的名字。想到还可以通过解析字节码得到,参考了 dis 模块的源码:

   1 import sys
   2 import opcode
   3 
   4 def get_name(obj):
   5     frame = sys._getframe(1)
   6     code = frame.f_code.co_code
   7     index = frame.f_lasti
   8     op = opcode.opname[ord(code[index-3])]
   9     oparg = ord(code[index-2]) + ord(code[index-1])*256
  10     if op in ('LOAD_NAME', 'LOAD_GLOBAL'):
  11         return frame.f_code.co_names[oparg]
  12     elif op == 'LOAD_FAST':
  13         return frame.f_code.co_varnames[oparg]
  14     else:
  15         raise Exception("Can not determine the name of the argument")
  16 
  17 if __name__ == '__main__':
  18     bbb = asdfasdf = {}
  19     print get_name(asdfasdf)
  20     print get_name(bbb)

输出::

asdfasdf
bbb


反馈

创建 by -- ZoomQuiet [2011-11-06 09:20:03]

MiscItems/2011-11-05 (last edited 2011-11-06 09:20:05 by ZoomQuiet)