2016-12-18 54 views
0
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__) 

任何人都可以帮我解决这两个问题吗?获取Python模块属性的名称和类型

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

我不明白为什么sys.__name__作为参数传递给函数。它应该是模块的名称。为什么.__name__添加到sys

而在for循环num, attr是检查在此:

enumerate(dir(eval(mod_name))) 

这是什么?它是一个内存位置吗?

+0

正如你所说,它应该是模块的名称。 'module .__ name__' **是** module的名字; 'sys .__ name__ =='sys''。不,这不是*“一个内存位置”* - 我建议你去Python文档并查看“eval”,“dir”和“enumerate”是做什么的,或者只是添加一些print函数调用来查找了解每一步做什么。 – jonrsharpe

回答

0

为什么.__name__已添加到sys?

每个模块都有一个__name__属性附加到它的名称。事情就是这样。

这是什么?它是一个内存位置吗?

不,笔者决定使用eval(出于某种原因),以评估(sys.__name__)传递的字符串并取回模块对象。我看不出为什么他决定这样做,让函数接收一个arg然后传递给eval是非常危险的,所以不要这么做。

这更好的实现(不使用inspect模块)是这样的:

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,如果你只是直接通过模块对象不是必需的。即使您确实通过了__name__,您仍然可以通过更安全的方式通过sys.modules取回模块。