Andru Asked:2020-01-07 11:24:16 +0000 UTC2020-01-07 11:24:16 +0000 UTC 2020-01-07 11:24:16 +0000 UTC 你怎么知道一个函数是否为空? 772 如何找出函数或方法是否有主体?也就是说,不仅仅是 def f(): pass python 3 个回答 Voted Best Answer Andrio Skur 2020-01-07T12:38:59Z2020-01-07T12:38:59Z 这是一种更稳定的方法(inspect.getsourcelines并不总是有效) import dis def check(function): instructions = dis.get_instructions(function) instr = next(instructions, None) if (instr is None) or (instr.opname != 'LOAD_CONST') or (instr.argrepr != 'None'): return False instr = next(instructions, None) return instr and (instr.opname == 'RETURN_VALUE') 这个怎么运作?每个函数都有一个__code__包含操作码字节串的属性。一个空函数只有 2 个操作码LOAD_CONST(загрузить None в стек)和RETURN_VALUE(вернуть то что в стеке(то есть None)). 我们相应地检查。 gil9red 2020-01-07T12:34:03Z2020-01-07T12:34:03Z 使用inspect.getsourcelines方法,分析函数内容: def foo(): pass import inspect lines = inspect.getsourcelines(foo) print(lines) # (['def foo():\n', ' pass\n'], 7) print(lines[0][-1].strip() == 'pass') # True jfs 2020-01-08T00:56:39Z2020-01-08T00:56:39Z Python 中的函数总是会做一些事情,因为所有 Python 函数都会在成功时返回一个值,所以至少有代码返回None. 例子: def f(): pass def f(): '' def f(): return def f(): return None f = lambda: None 所有这些函数在我的 Python 版本上都有几乎相同的字节码: >>> import dis >>> dis.dis(f) 2 0 LOAD_CONST 0 (None) 2 RETURN_VALUE (值得一提的是,字节码的存在以及dis模块生成的具体结果都是所选CPython版本的实现细节。Python本身并不要求存在字节码)。 在源代码级别和 AST 级别,这些功能不同: >>> import ast >>> def dump_ast(func_source): return ast.dump(ast.parse(func_source, 'exec').body[0]) ... >>> dump_ast("def f(): pass") "FunctionDef(name='f', args=arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[Pass()], decorator_list=[], returns=None, docstring=None)" >>> dump_ast("def f(): ''") "FunctionDef(name='f', args=arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[], decorator_list=[], returns=None, docstring='')" (值不同body, docstring)。 形式上,这里的函数体只有第二种情况是空的。 使用什么来确定什么是“空函数”:源代码、AST、字节码 - 取决于您的任务。 并非所有函数都在纯 Python 中定义,例如,像这样的内置函数len()可以用另一种语言(C、Java、RPython——取决于 Python 的实现)定义: >>> import inspect >>> inspect.isbuiltin(f) False >>> inspect.isbuiltin(len) True 或外部函数: >>> import ctypes >>> libc = ctypes.CDLL(None) >>> libc.printf(b"abc\n") abc 4 >>> inspect.isbuiltin(libc.printf) False 同样,这些函数是否被认为是“空的”取决于任务(不同的选项在不同的情况下可能是有益的)。
这是一种更稳定的方法(
inspect.getsourcelines并不总是有效)这个怎么运作?每个函数都有一个
__code__包含操作码字节串的属性。一个空函数只有 2 个操作码LOAD_CONST(загрузить None в стек)和RETURN_VALUE(вернуть то что в стеке(то есть None)). 我们相应地检查。使用inspect.getsourcelines方法,分析函数内容:
Python 中的函数总是会做一些事情,因为所有 Python 函数都会在成功时返回一个值,所以至少有代码返回
None.例子:
所有这些函数在我的 Python 版本上都有几乎相同的字节码:
(值得一提的是,字节码的存在以及
dis模块生成的具体结果都是所选CPython版本的实现细节。Python本身并不要求存在字节码)。在源代码级别和 AST 级别,这些功能不同:
(值不同
body,docstring)。形式上,这里的函数体只有第二种情况是空的。
使用什么来确定什么是“空函数”:源代码、AST、字节码 - 取决于您的任务。
并非所有函数都在纯 Python 中定义,例如,像这样的内置函数
len()可以用另一种语言(C、Java、RPython——取决于 Python 的实现)定义:或外部函数:
同样,这些函数是否被认为是“空的”取决于任务(不同的选项在不同的情况下可能是有益的)。