如何在Python中获取对象的名称?
有没有办法在Python中获取对象的名称?例如:如何在Python中获取对象的名称?,python,introspection,Python,Introspection,有没有办法在Python中获取对象的名称?例如: my_list = [x, y, z] # x, y, z have been previously defined for bla in my_list: print "handling object ", name(bla) # <--- what would go instead of `name`? # do something to bla 我从命令行获取函数名,并希望调用相关函数: func_name = p
my_list = [x, y, z] # x, y, z have been previously defined
for bla in my_list:
print "handling object ", name(bla) # <--- what would go instead of `name`?
# do something to bla
我从命令行获取函数名,并希望调用相关函数:
func_name = parse_commandline()
fun_dict[func_name]()
我之所以想要函数名,是因为我想创建fun\u dict
,而不需要写两次函数名,因为这似乎是创建bug的好方法。我想做的是:
fun_list = [fun1, fun2, fun3] # and I'll add more as the need arises
fun_dict = {}
[fun_dict[name(t) = t for t in fun_list] # <-- this is where I need the name function
fun_list=[fun1,fun2,fun3]#我会根据需要添加更多内容
fun_dict={}
[fun_dict[name(t)=t表示fun_列表中的t]#对象在Python中不一定有名称,因此无法获取名称
对象在有名称的情况下有属性并不少见,但这不是标准Python的一部分,大多数内置类型都没有名称
当你创建一个变量时,比如上面的x,y,z
,那么这些名称只是作为对象的“指针”或“引用”。对象本身不知道你在用什么名称,你也不容易(如果有的话)得到该对象的所有引用的名称
更新:但是,函数确实有一个\uuuuu名称\uuuuu
(除非它们是),因此,在这种情况下,您可以执行以下操作:
dict([(t.__name__, t) for t in fun_list])
这实际上是不可能的,因为可能有多个变量具有相同的值,或者一个值可能没有变量,或者一个值可能只是碰巧与一个变量具有相同的值
如果你真的想这样做,你可以使用
def variable_for_value(value):
for n,v in globals().items():
if v == value:
return n
return None
但是,如果您首先对名称进行迭代会更好:
my_list = ["x", "y", "z"] # x, y, z have been previously defined
for name in my_list:
print "handling variable ", name
bla = globals()[name]
# do something to bla
变量名可以在globals()和locals()目录中找到。但它们不能提供您在上面所查找的内容。“bla”将包含my_列表中每个项目的值,而不是变量。请注意,尽管如前所述,对象通常不知道也不知道哪些变量绑定到它们,但使用def
定义的函数在\uu name\uu
属性中有名称(在def
中使用的名称)。此外,如果函数在同一模块中定义(如示例中所示),则globals()
将包含所需词典的超集
def fun1:
pass
def fun2:
pass
def fun3:
pass
fun_dict = {}
for f in [fun1, fun2, fun3]:
fun_dict[f.__name__] = f
通常,当您想要执行类似的操作时,您可以创建一个类来保存所有这些函数,并使用一些清晰的前缀cmd\uu
或类似名称对它们进行命名。然后从命令中获取字符串,并尝试从前缀为cmd\u
的类中获取该属性。现在,您只需添加一个新的函数即可打开/method,调用方可以使用它。您可以使用文档字符串自动创建帮助文本
如其他答案中所述,您可以对模块中的globals()
和常规函数执行相同的方法,以更紧密地匹配您的要求
大概是这样的:
class Tasks:
def cmd_doit(self):
# do it here
func_name = parse_commandline()
try:
func = getattr('cmd_' + func_name, Tasks())
except AttributeError:
# bad command: exit or whatever
func()
下面是另一种思考方法。假设有一个name()
函数返回其参数的名称。给定以下代码:
def f(a):
return a
b = "x"
c = b
d = f(c)
e = [f(b), f(c), f(d)]
name(e[2])
应该返回什么,为什么
我之所以想要函数名,是因为我想创建fun\u dict
,而不需要写两次函数名,因为这似乎是创建bug的好方法
为此,您有一个很棒的函数,它允许您通过已知名称获取对象。因此,您可以执行以下操作:
funcs.py:
def func1(): pass
def func2(): pass
import funcs
option = command_line_option()
getattr(funcs, option)()
main.py:
def func1(): pass
def func2(): pass
import funcs
option = command_line_option()
getattr(funcs, option)()
使用反向命令
fun_dict = {'fun1': fun1,
'fun2': fun2,
'fun3': fun3}
r_dict = dict(zip(fun_dict.values(), fun_dict.keys()))
相反的dict会将每个函数引用映射到您在fun_dict中给出的确切名称,该名称可能是您定义函数时使用的名称,也可能不是。而且,这种技术可以推广到其他对象,包括整数
为了获得更多的乐趣和疯狂,您可以将正向和反向值存储在同一个目录中。如果您将字符串映射到字符串,我不会这样做,但如果您正在执行函数引用和字符串之类的操作,这并不太疯狂。此一行程序适用于所有类型的对象,只要它们位于globals()中
dict,它们应该是:
def name_of_global_obj(xx):
return [objname for objname, oid in globals().items()
if id(oid)==id(xx)][0]
或者,相当于:
def name_of_global_obj(xx):
for objname, oid in globals().items():
if oid is xx:
return objname
如果您想获取解释器中定义的函数或lambda或其他类似函数的对象的名称,可以使用dill.source.getname
from。它几乎可以查找\uuu name\uuuu
方法,但在某些情况下,它知道如何找到名称的其他魔法…或者为我不想陷入关于为python对象查找一个真实名称的争论,不管这意味着什么
>>> from dill.source import getname
>>>
>>> def add(x,y):
... return x+y
...
>>> squared = lambda x:x**2
>>>
>>> print getname(add)
'add'
>>> print getname(squared)
'squared'
>>>
>>> class Foo(object):
... def bar(self, x):
... return x*x+x
...
>>> f = Foo()
>>>
>>> print getname(f.bar)
'bar'
>>>
>>> woohoo = squared
>>> plus = add
>>> getname(woohoo)
'squared'
>>> getname(plus)
'add'
我在想同样的问题时偶然发现了这一页
正如其他人所指出的,从函数中获取\uuuu name\uuuu
属性以确定函数的名称非常简单。对于没有合理方法确定\uuu name\uuu
的对象,例如基本/基本对象,如basestring实例、int、long等,这稍微复杂一些
长话短说,您可能可以使用inspect模块对它是哪一个进行有根据的猜测,但是您可能必须知道您在堆栈中工作/遍历哪个帧才能找到正确的帧。但是我不想想象处理eval/exec'ed代码会有多大的乐趣
% python2 whats_my_name_again.py
needle => ''b''
['a', 'b']
[]
needle => '<function foo at 0x289d08ec>'
['c']
['foo']
needle => '<function bar at 0x289d0bfc>'
['f', 'bar']
[]
needle => '<__main__.a_class instance at 0x289d3aac>'
['e', 'd']
[]
needle => '<function bar at 0x289d0bfc>'
['f', 'bar']
[]
%
正如其他人所提到的,这是一个非常棘手的问题。解决这个问题的方法不是“一刀切”,甚至不是一蹴而就。困难(或轻松程度)实际上取决于你的情况
我曾多次遇到这个问题,但最近是在创建调试函数时。我希望函数将一些未知对象作为参数,并打印它们声明的名称和内容。获取内容当然很容易,但声明的名称是另一回事
下面是我的一些想法
返回函数名
决定素
name_of_function = lambda x : x.__name__
def name_of_function(arg):
try:
return arg.__name__
except AttributeError:
pass`
def name_of_object(arg):
# check __name__ attribute (functions)
try:
return arg.__name__
except AttributeError:
pass
for name, value in globals().items():
if value is arg and not name.startswith('_'):
return name
def names_of_object(arg):
results = [n for n, v in globals().items() if v is arg and not n.startswith('_')]
return results[0] if len(results) is 1 else results if results else None
class example:
def __init__(self, name):
self.name = name
def __unicode__(self):
return self.name
def get_name_of_obj(obj, except_word = ""):
for name, item in globals().items():
if item == obj and name != except_word:
return name
for each_item in [objA, objB, objC]:
get_name_of_obj(obj, "each_item")
>>> objA = [1, 2, 3]
>>> objB = ('a', {'b':'thi is B'}, 'c')
>>> for each_item in [objA, objB]:
... get_name_of_obj(each_item)
...
'objA'
'objB'
>>>
>>>
>>> for each_item in [objA, objB]:
... get_name_of_obj(each_item)
...
'objA'
'objB'
>>>
>>>
>>> objC = [{'a1':'a2'}]
>>>
>>> for item in [objA, objB, objC]:
... get_name_of_obj(item)
...
'objA'
'item' <<<<<<<<<< --------- this is no good
'item'
>>> for item in [objA, objB]:
... get_name_of_obj(item)
...
'objA'
'item' <<<<<<<<--------this is no good
>>>
>>> for item in [objA, objB, objC]:
... get_name_of_obj(item, "item")
...
'objA'
'objB' <<<<<<<<<<--------- now it's ok
'objC'
>>>
[k for k,v in locals().items() if v is myobj]
>>> a = 1
>>> this_is_also_a = a
>>> this_is_a = a
>>> b = "ligma"
>>> c = [2,3, 534]
>>> [k for k,v in locals().items() if v is a]
['a', 'this_is_also_a', 'this_is_a']
import foo
func_name = parse_commandline()
method_to_call = getattr(foo, func_name)
result = method_to_call()
import foo
result = getattr(foo, parse_commandline())()