我如何获取一个对象的名称?

2025-02-13 08:36:00
admin
原创
39
摘要:问题描述:假设我有如下代码:x = 0 y = 1 z = 2 my_list = [x, y, z] for item in my_list: print("handling object ", name(item)) # <--- what would go inst...

问题描述:

假设我有如下代码:

x = 0
y = 1
z = 2

my_list = [x, y, z]

for item in my_list:
    print("handling object ", name(item)) # <--- what would go instead of `name`?

如何在 Python 中获取每个对象的名称?也就是说:我可以name在这段代码中写什么来代替,以便循环显示handling object x然后handling object yhandling object z


在我的实际代码中,我有一个函数字典,稍后我将在使用用户输入查找它们后调用它们:

def fun1():
    pass
def fun2():
    pass
def fun3():
    pass

fun_dict = {'fun1': fun1,
            'fun2': fun2,
            'fun3': fun3}

# suppose that we get the name 'fun3' from the user
fun_dict['fun3']()

如何fun_dict自动创建,而不用写两次函数名?我希望能够写类似

fun_list = [fun1, fun2, fun3] # and I'll add more as the need arises

fun_dict = {}
for t in fun_list:
    fun_dict[name(t)] = t

以避免重复名称。


解决方案 1:

在 Python 中对象不一定有名称,因此你无法获取名称。

当您创建一个变量时(如上所示x, y, z),这些名称仅充当对象的“指针”或“引用”。对象本身并不知道您为其使用了什么名称,并且您无法轻松(如果有的话)获取对该对象的所有引用的名称。

但是,对象拥有属性并不罕见__name__。函数确实有属性__name__(除非它们是lambda 表达式),因此我们可以fun_dict通过以下方式构建:

fun_dict = {t.__name__: t for t in fun_list)

解决方案 2:

这实际上是不可能的,因为可能有多个变量具有相同的值,或者一个值可能没有变量,或者一个值可能恰好具有与变量相同的值。

如果你真的想这样做,你可以使用

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

 

解决方案 3:

正如其他人提到的,这是一个非常棘手的问题。解决方案并不是“一刀切”,甚至远远不是。难度(或容易程度)实际上取决于您的情况。

我多次遇到过这个问题,但最近一次是在创建一个调试函数时。我希望该函数将一些未知对象作为参数并打印其声明的名称和内容。获取内容当然很容易,但声明的名称则是另一回事。

以下是我所想到的一些内容。

返回函数名称

确定函数的名称非常容易,因为它具有包含函数声明名称的__name__属性。

name_of_function = lambda x : x.__name__

def name_of_function(arg):
    try:
        return arg.__name__
    except AttributeError:
        pass`

仅举一个例子,如果你创建函数def test_function(): pass,那么copy_function = test_functionname_of_function(copy_function)它将返回test_function

返回第一个匹配的对象名称

  1. 检查对象是否具有name属性,如果有则返回该属性(仅限声明函数)。请注意,您可以删除此测试,因为名称仍将保留在 中globals()

  2. 将 arg 的值与项中的值进行比较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

返回所有匹配的对象名称

  • 将 arg 的值与项的值进行比较globals(),并将名称存储在列表中。请注意,我过滤掉了以“_”开头的名称。

结果将由一个列表(用于多个匹配)、一个字符串(用于单个匹配)组成,否则为 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

解决方案 4:

这一行代码适用于所有类型的对象,只要它们在globals()字典中,它们应该是:

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

解决方案 5:

如果您要获取在解释器中定义的函数或 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'

解决方案 6:

使用反向字典。

fun_dict = {'fun1': fun1,
            'fun2': fun2,
            'fun3': fun3}

r_dict = dict(zip(fun_dict.values(), fun_dict.keys()))

反向字典会将每个函数引用映射到您在 fun_dict 中为其指定的确切名称,该名称可能是也可能不是您定义函数时使用的名称。而且,这种技术可以推广到其他对象,包括整数。

为了更加有趣和疯狂,您可以将正向和反向值存储在同一个字典中。如果您将字符串映射到字符串,我不会这样做,但如果您正在执行函数引用和字符串之类的操作,那就不太疯狂了。

解决方案 7:

请注意,尽管如上所述,对象通常不知道也无法知道与它们绑定的变量,但用 定义的函数def__name__属性中确实有名称(在 中使用的名称def)。此外,如果函数在同一个模块中定义(如您的示例所示),则将globals()包含您想要的字典的超集。

def fun1:
  pass
def fun2:
  pass
def fun3:
  pass

fun_dict = {}
for f in [fun1, fun2, fun3]:
  fun_dict[f.__name__] = f

解决方案 8:

这是另一种思考方式。假设有一个name()函数返回其参数的名称。给出以下代码:

def f(a):
    return a

b = "x"
c = b
d = f(c)

e = [f(b), f(c), f(d)]

应该name(e[2])返回什么?为什么?

解决方案 9:

我之所以想要有函数名称是因为我想在创建时fun_dict不用写两次函数名称,因为这似乎是创建错误的好方法。

为此,您可以使用一个很棒的getattr函数,它允许您通过已知名称获取对象。因此,您可以这样做:

funcs.py:

def func1(): pass
def func2(): pass

main.py:

import funcs
option = command_line_option()
getattr(funcs, option)()

解决方案 10:

我知道这是迟来的回答。

  1. 要获取函数名称,您可以使用func.__name__

  2. name获取没有或方法的任何 Python 对象的名称__name__。您可以迭代其模块成员。

前任:。

# package.module1.py

obj = MyClass()



# package.module2.py
import importlib
def get_obj_name(obj):
   mod = Obj.__module__ # This is necessary to 
   module = module = importlib.import_module(mod)
   for name, o in module.__dict__.items():
      if o == obj:
         return name

性能说明:不要在大型​​模块中使用它。

解决方案 11:

变量名可以在 globals() 和 locals() 字典中找到。但它们不会提供您在上面寻找的内容。“bla”将包含 my_list 中每一项的值,而不是变量。

解决方案 12:

通常,当您想要执行此类操作时,您会创建一个类来保存所有这些函数,并使用一些清晰的前缀cmd_或类似名称来命名它们。然后,您从命令中获取字符串,并尝试从带有前缀的类中获取该属性cmd_。现在,您只需向类添加一个新函数/方法,它就可以供调用者使用。并且您可以使用文档字符串自动创建帮助文本。

正如其他答案所述,您可能能够使用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()

解决方案 13:

当我思考同样的问题时,我偶然发现了这个页面。

正如其他人所指出的,只需__name__从函数中获取属性即可确定函数的名称,这很简单。对于没有合理方法确定的对象__name__,即基本/原始对象(如 basestring 实例、int、long 等),这稍微有点棘手。

长话短说,您可能可以使用检查模块来猜测它是哪一个,但您可能必须知道您正在处理/遍历堆栈中的哪个框架才能找到正确的框架。但我不敢想象处理 eval/exec 代码会有多有趣。

% 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']
[]
%

再次输入我的姓名.py:

#!/usr/bin/env python

import inspect

class a_class:
    def __init__(self):
        pass

def foo():
    def bar():
        pass

    a = 'b'
    b = 'b'
    c = foo
    d = a_class()
    e = d
    f = bar

    #print('globals', inspect.stack()[0][0].f_globals)
    #print('locals', inspect.stack()[0][0].f_locals)

    assert(inspect.stack()[0][0].f_globals == globals())
    assert(inspect.stack()[0][0].f_locals == locals())

    in_a_haystack = lambda: value == needle and key != 'needle'

    for needle in (a, foo, bar, d, f, ):
        print("needle => '%r'" % (needle, ))
        print([key for key, value in locals().iteritems() if in_a_haystack()])
        print([key for key, value in globals().iteritems() if in_a_haystack()])


foo()

解决方案 14:

你定义一个class并添加Unicode私有函数插入class类似

class example:
  def __init__(self, name):
    self.name = name

  def __unicode__(self):
    return self.name

当然,您必须添加额外的变量self.name,即对象的名称。

解决方案 15:

这是我的答案,我也在使用 globals().items()

    def get_name_of_obj(obj, except_word = ""):

        for name, item in globals().items():
            if item == obj and name != except_word:
                return name

我添加了 except_word,因为我想过滤掉 for 循环中使用的一些单词。如果你没有添加它,for 循环中的关键字可能会混淆此函数,有时像以下案例中的“each_item”这样的关键字可能会显示在函数的结果中,这取决于你对循环做了什么。

例如。

    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'
    >>>

希望这能有所帮助。

解决方案 16:

根据您要尝试执行的操作,您可以使用这种方法。

就你的情况而言,你的函数将全部位于模块 foo 中。然后你可以:

import foo

func_name = parse_commandline()
method_to_call = getattr(foo, func_name)
result = method_to_call()

或者更简洁地说:

import foo

result = getattr(foo, parse_commandline())()

解决方案 17:

Python 具有映射到哈希映射(称为命名空间)中的对象的名称。在任何时间点,一个名称始终只引用一个对象,但单个对象可以由任意数量的名称引用。给定一个名称,哈希映射可以非常高效地查找该名称所引用的单个对象。但是,给定一个对象(如上所述,它可以由多个名称引用),则没有有效的方法来查找引用它的名称。您需要做的是遍历命名空间中的所有名称并分别检查每个名称,看看它是否映射到给定的对象。这可以通过列表推导轻松完成:

[k for k,v in locals().items() if v is myobj]

这将计算出一个字符串列表,其中包含当前映射到对象的所有本地“变量”的名称 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']

当然locals()可以替换为dict您想要搜索指向给定对象的名称的任何内容。显然,对于非常大的命名空间,这种搜索可能会很慢,因为必须完整地遍历它们。

解决方案 18:

你可以尝试

_ = [print(type(e).__name__) for e in entities]

用于对象集合entities

解决方案 19:

你好,有一种方法可以获取存储类实例的变量名称,那就是使用

当地人()

函数,它返回一个包含变量名称(字符串)及其值的字典

解决方案 20:

它不仅可以传递 val,还可以传递 name 和 val 的数组。例如

x = [name, val]
y = [name2, val2]
this = [x, y]

for i in this:
    name = i[0]
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用