(dir(__builtins__)) 输出:151
我用数字和字符串对它们进行了分类:
# categorize with number
number_dict = {}
for i in all_builtins:
if type(eval(i)) not in number_dict:
number_dict[type(eval(i))] = 1
else:
number_dict[type(eval(i))] += 1
# get number_dict
{<class 'type'>: 92, <class 'ellipsis'>: 1, ....}
# categorize with string
string_dict = {}
for i in all_builtins:
if type(eval(i)) not in string_dict:
string_dict[type(eval(i))] = i
else:
string_dict[type(eval(i))] += "," + i
# get string_dict
string_dict = {...<class 'str'>: '__name__', <class'_sitebuiltins._Printer'>: 'copyright,credits,license',<class '_sitebuiltins.Quitter
'>: 'exit,quit', <class '_sitebuiltins._Helper'>: 'help'}
如何使用列表或更高级的 pythonic 对内置函数进行分类?
最佳答案
使用 Counter
和 getattr
而不是 eval
进行计数,这样它也适用于其他模块对象:
>>> import collections
>>> collections.Counter(type(getattr(__builtins__, name)) for name in dir(__builtins__))
Counter({<type 'type'>: 76, <type 'builtin_function_or_method'>: 52, <class 'site._Printer'>: 3, <type 'bool'>: 3, <type 'str'>: 2, <class 'site.Quitter'>: 2, <type 'NoneType'>: 2, <class 'site._Helper'>: 1, <type 'NotImplementedType'>: 1, <type 'ellipsis'>: 1})
第二个使用一个函数将 (k,v)
的列表累积到 k:[v]
的字典中:
def accumulate(kv):
d = {}
for k,v in kv:
d.setdefault(k,[]).append(v)
return d
accumulate((type(getattr(__builtins__, name)), name) for name in dir(__builtins__))
这是一个运行示例:
>>> accumulate((type(getattr(__builtins__, name)), name) for name in dir(__builtins__))
{<class 'site._Helper'>: ['help'], <type 'str'>: ['__doc__', '__name__'], <class 'site.Quitter'>: ['exit', 'quit'], <type 'type'>: ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError', 'EnvironmentError', 'Exception', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', 'basestring', 'bool', 'buffer', 'bytearray', 'bytes', 'classmethod', 'complex', 'dict', 'enumerate', 'file', 'float', 'frozenset', 'int', 'list', 'long', 'memoryview', 'object', 'property', 'reversed', 'set', 'slice', 'staticmethod', 'str', 'super', 'tuple', 'type', 'unicode', 'xrange'], <type 'NotImplementedType'>: ['NotImplemented'], <class 'site._Printer'>: ['copyright', 'credits', 'license'], <type 'bool'>: ['False', 'True', '__debug__'], <type 'NoneType'>: ['None', '__package__'], <type 'ellipsis'>: ['Ellipsis'], <type 'builtin_function_or_method'>: ['__import__', 'abs', 'all', 'any', 'apply', 'bin', 'callable', 'chr', 'cmp', 'coerce', 'compile', 'delattr', 'dir', 'divmod', 'eval', 'execfile', 'filter', 'format', 'getattr', 'globals', 'hasattr', 'hash', 'hex', 'id', 'input', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'locals', 'map', 'max', 'min', 'next', 'oct', 'open', 'ord', 'pow', 'print', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'round', 'setattr', 'sorted', 'sum', 'unichr', 'vars', 'zip'], <class 'collections.Counter'>: ['_']}
eval
不是什么对象的问题,而是它如何查找名称的问题。事实上,getattr
认为它的参数只是一个名字。但是 eval
将处理 1+evil()
不是作为属性名称而是作为调用。
考虑在我设置 setattr(__builtins__, '1+evil()', '')
之后 eval
会做什么:
>>> setattr(__builtins__, '1+evil()', '')
>>> getattr(__builtins__, '1+evil()')
''
>>> eval('1+evil()')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'evil' is not defined
如果有一个evil
函数,它就会被调用。但是由于没有定义这样的 evil
函数,我们得到一个 NameError
。
此外,eval
之所以有效,是因为 __builtins__
中的所有值都在 globals()
中。一旦您将 __builtins__
替换为任何其他模块,eval
将无法解析名称,除非您将 vars(that_module)
作为其传递给 eval globals
参数。
关于 python 3 : How to categorize all the 151 builtins in a single code line?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45557361/