February 26, 2024

Python 魔法方法利用注意

我们先看一个报错

image-20241022173651605

在 Python 中,__init__ 方法属于类的实例方法,但它本质上是通过 method-wrapperwrapper_descriptor 实现的特殊方法,而不是常规的函数对象。这就是为什么在访问 __init__ 的时候会看到 method-wrapper,并且无法访问像 __globals__ 这样的属性。

__init__ 是一个特殊方法__init__ 是类的构造函数(初始化方法),它是一个绑定方法,调用时由 Python 自动处理。这种特殊的绑定方法不像普通的函数或方法那样包含 __globals__ 属性,因为它是通过内部机制实现的,而不是像常规函数那样存在于全局命名空间。

**绑定方法和 method-wrapper**: 通过 obj.__init__ 访问 __init__ 实际上返回的是一个绑定到对象的 method-wrapper,它是 Python 的一种优化机制,用于类的魔法方法。method-wrapper 并不暴露 __globals__ 属性,因为它与普通函数不同,不能直接通过 globals() 访问其全局变量。

__globals__ 仅适用于函数对象: 只有普通的函数对象(如通过 def 定义的函数)才会有 __globals__ 属性,表示它们所在的全局命名空间。Python 的内建方法(如 __init__)是用 C 实现的,属于特殊的 method-wrapper,因此不具备 __globals__ 属性。

重点在第三点,能够有globals属性的必须是def定义的函数(lambda也可以

image-20241022174223178

image-20241022174511612

很清晰了,函数能直接访问他所在模块的所有变量和属性,你看test3已经访问到了之前定义的匿名函数。

所以我们的目的一般都是通过访问类或者实例来访问函数的globals属性

image-20241022174549243

总结

Python 的内置魔法方法(如 __init__)是特殊的绑定方法(method-wrapper),不具备 __globals__ 属性。

只有通过 def 定义的普通函数和方法才具有 __globals__ 属性,表示它们的全局命名空间。

要访问 __globals__,请确保操作的对象是常规的函数或方法对象,而不是内建的魔法方法。

About this Post

This post is written by void2eye, licensed under CC BY-NC 4.0.

#Web