Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中获取对象的名称?_Python_Introspection - Fatal编程技术网

如何在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

有没有办法在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 = 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())()