Nat*_*man 29 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
Run Code Online (Sandbox Code Playgroud)
编辑:一些上下文:
我实际上在做的是创建一个我可以通过命令行指定的函数列表.
我有:
def fun1:
pass
def fun2
pass
def fun3:
pass
fun_dict = {'fun1': fun1,
'fun2': fun2,
'fun3': fun3}
Run Code Online (Sandbox Code Playgroud)
我从命令行获取函数的名称,我想调用相关函数:
func_name = parse_commandline()
fun_dict[func_name]()
Run Code Online (Sandbox Code Playgroud)
我想拥有该函数名称的原因是因为我想创建fun_dict两次函数的名称,因为这似乎是创建错误的好方法.我想做的是:
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
Run Code Online (Sandbox Code Playgroud)
这样我只需要写一次函数名.
Len*_*bro 30
对象不一定在python中有名称,因此您无法获取名称.对象__name__在这些情况下具有属性并不常见,因为它们具有名称,但这不是标准python的一部分,并且大多数内置类型没有.
当您创建一个变量(如上面的x,y,z)时,这些名称就会充当对象的"指针"或"引用".对象本身不知道您使用的是什么名称,并且您不能轻易地(如果有的话)获取该对象的所有引用的名称.
更新:但是,函数确实有__name__(除非它们是lambdas)所以,在这种情况下你可以这样做:
dict([(t.__name__, t) for t in fun_list])
Run Code Online (Sandbox Code Playgroud)
Mar*_*wis 11
这实际上是不可能的,因为可能存在多个具有相同值的变量,或者值可能没有变量,或者值可能只是偶然地具有与变量相同的值.
如果你真的想这样做,你可以使用
def variable_for_value(value):
for n,v in globals().items():
if v == value:
return n
return None
Run Code Online (Sandbox Code Playgroud)
但是,如果你首先迭代名字会更好:
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
Run Code Online (Sandbox Code Playgroud)
Six*_*Six 11
正如其他人提到的,这是一个非常棘手的问题。解决这个问题的方法并不是“一刀切”,甚至远程解决方案也不是。困难(或容易)实际上取决于您的情况。
我曾多次遇到这个问题,但最近一次是在创建调试功能时。我希望该函数将一些未知对象作为参数并打印它们声明的名称和内容。获取内容当然很容易,但声明的名称则是另一回事了。
以下是我的一些想法。
确定函数的名称非常容易,因为它具有包含函数声明名称的__name__属性。
name_of_function = lambda x : x.__name__
def name_of_function(arg):
try:
return arg.__name__
except AttributeError:
pass`
Run Code Online (Sandbox Code Playgroud)
举个例子,如果你创建函数def test_function(): pass, then copy_function = test_function, then name_of_function(copy_function),它将返回test_function。
检查对象是否具有__name__属性,如果有则返回它(仅限声明的函数)。请注意,您可以删除此测试,因为名称仍将位于globals().
将 arg 的值与 in 中的项目值进行比较globals(),并返回第一个匹配项的名称。请注意,我正在过滤掉以“_”开头的名称。
结果将包含第一个匹配对象的名称,否则为 None。
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
Run Code Online (Sandbox Code Playgroud)
globals()将 arg 的值与列表中的项目值和存储名称进行比较。请注意,我正在过滤掉以“_”开头的名称。结果将包含一个列表(对于多个匹配)、一个字符串(对于单个匹配),否则为 None。当然,您应该根据需要调整此行为。
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
Run Code Online (Sandbox Code Playgroud)
这种单行代码适用于所有类型的对象,只要它们在命令中即可globals(),它们应该是:
def name_of_global_obj(xx):
return [objname for objname, oid in globals().items()
if id(oid)==id(xx)][0]
Run Code Online (Sandbox Code Playgroud)
或等效地:
def name_of_global_obj(xx):
for objname, oid in globals().items():
if oid is xx:
return objname
Run Code Online (Sandbox Code Playgroud)
如果要查找函数或lambda的名称或解释器中定义的其他类似函数的对象,可以使用dill.source.getnamefrom dill.它几乎寻找__name__方法,但在某些情况下,它知道如何找到名称的其他魔法...或对象的名称.我不想进入关于为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'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
86739 次 |
| 最近记录: |