biswa1991
biswa1991

Reputation: 546

Get names and types of a Python module's attributes

import sys


def attrs_and_types(mod_name):

    print('Attributes and their types for module {}:'.format(mod_name))
    print()

    for num , attr in enumerate(dir(eval(mod_name))):

        print("{idx}: {nam:30}  {typ}".format(
        idx=str(num + 1).rjust(4),
        nam=(mod_name + '.' + attr).ljust(30), 
        typ=type(eval(mod_name + '.' + attr))))

attrs_and_types(sys.__name__)

Can anyone help me with these two lines?

for num, attr in enumerate(dir(eval(mod_name))):
    attrs_and_types(sys.__name__)

I don't understand why sys.__name__ is passed as an argument to the function. It's supposed to be the name of the module. Why is .__name__ added to sys?

And in the for loop num, attr is checking in this:

enumerate(dir(eval(mod_name)))

What is this? Is it a memory location?

Upvotes: 1

Views: 131

Answers (1)

Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

Reputation: 160447

Why is .__name__ added to sys?

Every module has a __name__ attribute attached to it that has its name. It's just how things are.

What is this? Is it a memory location?

Nope, the author decided to use eval (for some reason) to evaluate the string passed (sys.__name__) and get back the module object. I cannot see why he decided to do so, it is quite dangerous to allow the function to receive an arg which you then pass to eval, so don't do this.

A better implementation for this (without using the inspect module) would look like this:

import sys

def attrs_and_types(mod):
    name = mod.__name__
    print('Attributes and their types for module {}:\n'.format(name))
    fmt = "{idx}: {nam:30}  {typ}"
    for num , attr in enumerate(dir(sys)):
        s = fmt.format(
            idx=str(num + 1).rjust(4),
            nam=(name + '.' + attr).ljust(30), 
            typ=type(attr)
        )
        print(s)

attrs_and_types(sys)

eval isn't required if you just pass the module object directly. Even if you did pass the __name__ though, you'd still be able to get back the module via sys.modules in a safer manner.

Upvotes: 1

Related Questions