【问题标题】:How to print a Python attribute name?如何打印 Python 属性名称?
【发布时间】:2016-07-02 08:51:04
【问题描述】:

假设我想创建一个内省节,它显示一个函数的可用细节。
类似于下面代码的底部:

def sample(_range=4):
    """ produce a range of integers """
    for i in range(_range):
        yield i

f = sample
for i in (f.__name__, f.__doc__, f.__dict__, f.__code__, f.__defaults__, f.__globals__, f.__closure__):
    print("XXX", i)

我未能实现的是将 XXX 更改为可以打印属性名称的内容,例如,而不是

XXX sample
XXX  produce a range of integers
XXX {}
XXX <code object sample at 0xfff15890, file "/tmp/tmp.py", line 1>
XXX (4,)
XXX {'__loader__': <_frozen_importlib.SourceFileLoader object at 0xfff13b30>, '__package__': None, '__file__': '/tmp/tmp.py', '__cached__': None, 'i': {...}, 'f': <function sample at 0xfff5b1e0>, '__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__spec__': None, '__name__': '__main__', 'sample': <function sample at 0xfff5b1e0>}
XXX None

我想要

__name__ sample
__doc__  produce a range of integers
__dict__ {}
__code__ <code object sample at 0xfff15890, file "/tmp/tmp.py", line 1>
__defaults__ (4,)
f.__globals__ {'__loader__': <_frozen_importlib.SourceFileLoader object at 0xfff13b30>, '__package__': None, '__file__': '/tmp/tmp.py', '__cached__': None, 'i': {...}, 'f': <function sample at 0xfff5b1e0>, '__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__spec__': None, '__name__': '__main__', 'sample': <function sample at 0xfff5b1e0>}
__closure__ None

你建议用什么替换XXX

【问题讨论】:

  • 你可以用字典吗?名称作为键,值作为属性
  • 为什么不迭代名称呢? for name in ['__name__', '__doc__', ...]: ....
  • @MosesKoledoye 在后台,这正是 sample 对象是什么!
  • @jonrsharpe 对!因此,将属性作为列表中的名称,就像您所做的那样,使用 getattr
  • 有疑问,就做print('__name__', f.__name__)?另外,查看inspect 模块。

标签: python python-3.x attributes eval introspection


【解决方案1】:

如果像您的示例一样,您知道所需属性的名称,这将起作用:

for fn in ('__name__', '__doc__', '__dict__', '__code__', '__defaults__', '__globals__', '__closure__'):
    print(fn, getattr(f, fn))

如果您在只有功能的情况下询问如何获取名称,那么我相信您不走运;名称不是函数的属性,而是它是如何被引用的,就像你不能从数字中问包含数字 3 的变量的名称是什么一样。 (思考题:作为 3 个不同对象的一部分的函数的名称是什么,每个对象都有不同的名称?)

我想,如果您想要特定对象中的函数名称,您可以遍历该对象的属性,搜索您的函数;当您找到它时,您用来引用它的名称就是您想要的名称。

【讨论】:

  • 应该是getattr(f, fn)
  • def foo(): pass 实际上将函数对象命名为foo。所以函数可以而且确实有名字;它只是你无法获得名称的变量。
【解决方案2】:

既然你已经有了一个属性列表,你可以使用getattr

for name in ['__name__', '__doc__', '__dict__', '__code__', '__defaults__', '__globals__', '__closure__']:
    print('{} -> {}'.format(name, getattr(f, name)))

【讨论】:

    猜你喜欢
    • 2015-10-23
    • 2016-12-27
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    • 2017-09-28
    相关资源
    最近更新 更多