如何防止 Python 函数使用任何变量(除了局部变量)?

为了防止 Python 函数使用除局部变量以外的任何变量,通过指定空的全局作用域和局部作用域执行代码,强制函数只能使用显式传递的变量。

在这里插入图片描述

问题背景

在进行 Python 代码重构时,为了确保不忘记纠正函数中的指令而导致原始代码出现问题,我们需要确保函数在测试时无法访问全局变量。除了将函数复制到单独的模块之外,还有哪些方法可以实现这一目的?

解决方案

  1. 使用单例模式管理全局变量

一种方法是将所有全局变量都放到一个单例(全局)对象中。这样做的好处是,任何对全局变量的使用都会非常明显,便于我们在日后减少或消除它们。

例如,我们可以在模块中进行如下全局声明:

dir_root = "/example/rootdir"
debug_level = 3

然后将它们包装在一个类中,并声明一个单例实例:

class GLOBALS:
  dir_root = ...
  debug_level = ...

Globals = GLOBALS()

当然,现有引用变量的地方都需要更新,以使用例如 Globals.dir_root 来代替直接使用 dir_root

这样做的好处是,它允许我们突出显示对全局变量的使用,同时保持应用程序逻辑不变。这种方式使我们可以以更加渐进的方式进行重构,从而减少引入新逻辑错误的可能性。根据我们的原始问题,我们可以确信任何不显式引用 Globals 对象的函数都不会使用任何全局变量。

2. 使用 functools.partial

另一种方法是使用 functools.partial 来创建函数对象的局部副本。我们可以使用 partial 来绑定函数的参数,同时还可以绑定函数所使用的全局变量。

例如,我们可以使用如下代码来创建一个局部副本的函数,该副本只能访问有限的全局变量:

from functools import partial

def big_function(args):
    def one_small_transformation(args):
        # No one else needs to see this transformation outside the function1

    def second_small_transformation(args):

    ...

    # Block of instructions chaining small transformations

# Other big functions and code making them work together

# Create a partial copy of `one_small_transformation` that only has access to `args`
one_small_transformation_partial = partial(one_small_transformation, args=args)

# Create a partial copy of `second_small_transformation` that only has access to `args`
second_small_transformation_partial = partial(second_small_transformation, args=args)

# Now, we can call these partial functions without worrying about them accessing any global variables
one_small_transformation_partial()
second_small_transformation_partial()

这种方法的好处是,它允许我们在不修改原始函数的情况下创建函数的局部副本。这使得我们可以轻松地测试函数,而无需担心对全局变量的意外访问。

代码示例

# Example 1: Using a singleton to manage global variables

class GLOBALS:
  dir_root = "/example/rootdir"
  debug_level = 3

Globals = GLOBALS()

def big_function(args):
    # Access the global variables using the Globals object
    dir_root = Globals.dir_root
    debug_level = Globals.debug_level

    # ...

# Example 2: Using functools.partial to create a partial copy of a function

from functools import partial

def big_function(args):
    def one_small_transformation(args):
        # No one else needs to see this transformation outside the function1

    def second_small_transformation(args):

    ...

    # Block of instructions chaining small transformations

# Create a partial copy of `one_small_transformation` that only has access to `args`
one_small_transformation_partial = partial(one_small_transformation, args=args)

# Create a partial copy of `second_small_transformation` that only has access to `args`
second_small_transformation_partial = partial(second_small_transformation, args=args)

# Now, we can call these partial functions without worrying about them accessing any global variables
one_small_transformation_partial()
second_small_transformation_partial()

希望这些解决方案对你有帮助。

总结一下

防止 Python 函数使用非局部变量的几种方法:

  1. 使用 exec 限制作用域:通过执行代码时控制作用域。
  2. 闭包定义:将函数限制在封闭的局部作用域中。
  3. 动态检查:通过 globals() 或字节码分析约束变量访问。
  4. 参数传递:所有变量显式通过参数传递。
  5. 自定义环境:用隔离的全局和局部环境执行函数。

根据需求选择适合的解决方案,其中闭包和参数传递是最通用和推荐的方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值