Python View类as_view为视图函数添加属性的原理及相关疑问
关于Python View类及函数属性的问题解答
问题1:Python的View类中as_view()函数是否会为视图函数添加新属性?
会。as_view()返回的view函数会被添加多个属性,包括自定义属性以及从View类、dispatch方法复制的属性。
问题2:解释View类as_view()函数中给view函数赋值属性的代码段含义
以下是对各赋值代码的逐一解释:
view.view_class = cls:将当前View类本身绑定到view函数的view_class属性,方便后续通过view函数反向获取对应的视图类。view.view_initkwargs = initkwargs:保存调用as_view()时传入的初始化参数,后续创建视图实例时会使用这些参数。view.__doc__ = cls.__doc__:把View类的文档字符串复制给view函数,保持文档信息的一致性。view.__module__ = cls.__module__:将View类所在的模块信息同步给view函数,确保模块归属正确。view.__annotations__ = cls.dispatch.__annotations__:复制dispatch方法的类型注解到view函数,保留类型提示信息。view.__dict__.update(cls.dispatch.__dict__):把dispatch方法的所有额外属性(比如@csrf_exempt这类装饰器添加的标记)复制到view函数,让view函数继承这些特性。
问题3:上述代码片段是否确实为view()函数添加了新属性?
是的。这些代码直接对view函数对象进行属性操作:
view.view_class和view.view_initkwargs是新增的自定义属性;__doc__、__module__、__annotations__是函数对象原本就有的特殊属性,这里是对其进行覆盖更新;__dict__.update(...)则是将dispatch方法的所有额外属性(如装饰器添加的属性)添加到view函数的属性字典中。
问题4:为何两段代码中,前者访问main().x可正常输出,后者调用main()()却报错?
核心差异在于操作对象的不同:
- 第一段代码
print(main().x)是获取返回的child函数对象的属性x,这个属性是直接绑定在函数对象上的,和函数内部的变量无关,所以能正常输出。 - 第二段代码
main()()是调用child函数,函数内部的print("I represent : "+x)中的x是函数作用域内的局部变量,但这个变量从未被定义或赋值,因此会抛出NameError错误。
要明确:函数对象的属性(比如child.x)和函数内部的变量(比如child里的x)是完全独立的两个东西,前者属于函数对象本身,后者属于函数执行时的作用域,两者没有关联。
内容的提问来源于stack exchange,提问作者boggy
相关产品推荐
相关产品推荐

