python - 如何确保 python 函数不依赖于外部变量?

标签 python debugging syntax functional-programming functional-testing

假设我定义了一个函数f(x),它在语法上是正确的。我想确保 f 可以“正常运行”,因为它的输出完全取决于输入 x

有时候,如果f的定义很复杂,可能会无意中(因为错别字,或者不够小心)在它的定义中引用了一些外部变量,这会导致错误很难找到。

是否有任何工具、任何“指令 pragma”(可以这么说)或任何“最佳实践”来确保不会发生这种情况?

例子:

xx = 1.0

def f(x, y, p=1):
    return xx * y**p # A typo here: should be x * y**p

如果在python中没有简单的方法可以实现,哪些语言有这样的功能?据我所知,C、C++和Fortran没有这个。 Fortran 95 有纯子程序和函数,但它被程序员用来“ promise ”一个子程序/函数不会修改任何外部变量,而子程序/函数仍然可以从它们中取值。

最佳答案

虽然有点 hackish,但您可以做这样的事情来检查函数代码对象中使用的指令:

import opcode  # see /Python/Lib/opcode.py

GLOBAL_INSTRUCTIONS = {opcode.opmap['DELETE_GLOBAL'],
                       opcode.opmap['LOAD_GLOBAL'],
                       opcode.opmap['STORE_GLOBAL']}

def is_pure(func):
    for inst in instructions(func.func_code.co_code):
        op = inst[0]
        if op in GLOBAL_INSTRUCTIONS:
            return False
    return True

def instructions(code):
    """Iterates over a code string yielding integer [op, arg] pairs
    """
    code = map(ord, code)
    i, L = 0, len(code)
    extended_arg = 0
    while i < L:
        op = code[i]
        i+= 1
        if op < opcode.HAVE_ARGUMENT:
            yield [op, None]
            continue
        oparg = code[i] + (code[i+1] << 8) + extended_arg
        extended_arg = 0
        i += 2
        if op == opcode.EXTENDED_ARG:
            extended_arg = oparg << 16
            continue
        yield [op, oparg]

xx = 1.0

def f(x, y, p=1):
    return xx * y**p # A typo here: should be x * y**p

def f2(x, y, p=1):
    return x * y**p # No typo

print(is_pure(f))   # --> False
print(is_pure(f2))  # --> True

关于python - 如何确保 python 函数不依赖于外部变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28948146/

相关文章:

r - 使用带有替换函数的 get()

python - 似乎无法让 pyqt 倒计时器工作

c# - 如何按 python 和 C# 中的第二个元组元素对列表进行排序

python - 无 Python 错误/错误?

python - Anaconda 接管了我的 Python 之路

java - 我可以在 Intellij Idea 中设置包级别或文件级别的断点吗?

debugging - 将汇编代码映射到 VB6 代码

c# - 如何处理 C# XNA 错误并针对已发布的游戏进行最佳调试?

c - C 中的数组语法混淆

objective-c - ObjC中圆括号和大括号括起来的几个语句的赋值