栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何通过手动填充__class__单元格使super()工作?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何通过手动填充__class__单元格使super()工作?

说真的:您真的不想这样做。

但是,这对于Python的高级用户了解这一点很有用,因此我将对其进行解释。

单元格和freevar是创建闭包时分配的值。例如,

def f():    a = 1    def func():        print(a)    return func

f
返回基于的闭包
func
,并存储对的引用
a
。该引用存储在一个单元中(实际上存储在一个freevar中,但这取决于实现)。您可以检查以下内容:

myfunc = f()# ('a',)print(myfunc.__pre__.co_freevars)# (<cell at 0xb7abce84: int object at 0x82b1de0>,)print(myfunc.__closure__)

(“ cells”和“
freevars”非常相似。Freevars具有名称,其中的单元格具有索引。它们都存储在中

func.__closure__
,单元格在前。我们只在
freevars
这里关心,因为那样的话
__class__
。)

一旦了解了这一点,就可以看到super()的实际工作原理。任何包含对的调用的函数

super
实际上都是一个闭包,具有一个名为freevar的闭包
__class__
(如果您引用
__class__
自己,也会添加该闭包):

class foo:    def bar(self):        print(__class__)

(警告:这就是事情变得邪恶的地方。)

这些单元格在中可见

func.__closure__
,但是是只读的。你不能改变它。更改它的唯一方法是创建一个新函数,该新函数由
types.FunctionType
构造函数完成。但是,您的
__init__
函数根本没有
__class__
freevar,因此我们需要添加一个。这意味着我们还必须创建一个新的代码对象。

下面的代码执行此操作。我

B
出于说明目的添加了基类。该代码进行了一些假设,例如。这
__init__
不已经有一个名为自由变量
__class__

这里还有另外一个技巧:似乎没有像元类型的构造函数。要解决此问题,将

C.dummy
创建一个虚拟函数,该函数具有我们需要的单元格变量。

import typesclass B(object):    def __init__(self):        print("base")class C(B):    def dummy(self): __class__def __init__(self):    print('calling __init__')    super().__init__()def MakeCodeObjectWithClass(c):    """    Return a copy of the pre object c, with __class__ added to the end    of co_freevars.    """    return types.CodeType(c.co_argcount, c.co_kwonlyargcount, c.co_nlocals, c.co_stacksize, c.co_flags, c.co_pre, c.co_consts, c.co_names, c.co_varnames, c.co_filename, c.co_name, c.co_firstlineno, c.co_lnotab, c.co_freevars + ('__class__',), c.co_cellvars)new_pre = MakeCodeObjectWithClass(__init__.__pre__)old_closure = __init__.__closure__ or ()C.__init__ = types.FunctionType(new_pre, globals(), __init__.__name__,    __init__.__defaults__, old_closure + (C.dummy.__closure__[0],))if __name__ == '__main__':    c = C()


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/648757.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号