简体   繁体   中英

How to print a Python attribute name?

Say I'd like to create an introspection stanza, that displays available details of a function.
Something like the bottom of the following code:

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)

What I'm failing to achieve is changing the XXX to something that would print the attribute name, eg, instead of

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

I'd like to have

__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

What would you suggest should replace XXX ?

If, as in your example, you know the names of the attributes you want, this would work:

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

If you are asking how to get the name when all you have is the function, then I believe you are out of luck; the name isn't a property of the function, but rather how it is referenced, much as you can't ask what the name of the variable containing the number 3 is just from the number. (Thought exercise: what would the name be for a function that is part of 3 distinct objects, each under a different name?)

I suppose, if you wanted the name of a function in a particular object, you could iterate over the attributes of that object, searching for your function; when you find it, the name you used to reference it would be the one you want.

Since you already have a list of the attributes, you could use getattr :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM