当前位置: 首页 > news >正文

详细介绍:Python 高手编程系列一十三:现实例子 — 延迟求值属性

这些属性的初始就是描述符的一个示例用法就是将类属性的初始化延迟到被实例访问时。要
化依赖全局应用上下文的话,那么这一点可能有用。另一个使用场景是初始化的代价很大,但
在导入类的时候不知道是否会用到这个属性。这样的描述符许可按照如下所示来实现:
class InitOnAccess:
def init(self, klass, *args, **kwargs):
self.klass = klass
self.args = args
self.kwargs = kwargs
self._initialized = None
def get(self, instance, owner):
if self._initialized is None:
print(‘initialized!’)
self._initialized = self.klass(*self.args,
**self.kwargs)
else:
print(‘cached!’)
return self._initialized
下面是示例用法:

class MyClass:
… lazily_ _initialized = InitOnAccess(list, “argument”)

m = MyClass()

m.lazily_initialized
initialized!
[‘a’, ‘r’, ‘g’, ‘u’, ‘m’, ‘e’, ‘n’, ‘t’]
m.lazily
initialized
cached!
[‘a’, ‘r’, ‘g’, ‘u’, ‘m’, ‘e’, ‘n’, ‘t’]
PyPI上OpenGL的官方Python库PyOpenGL用到了相似的技术来实现lazy_property,
内容描述符,如下所示:就是它既是装饰器又
class lazy_property(object):
def init(self, function):
self.fget = function
def get(self, obj, cls):
value = self.fget(obj)
setattr(obj, self.fget.name, value)
return value
这样的实现与使用 property 装饰器(稍后介绍)类似,但它所包装的函数仅执行一
次,然后类属性就被替换为它的返回值。当开发人员需要同时满足以下两点要求时,这种
技术通常很有用。
• 对象实例需要被保存为实例之间共享的类属性,以节约资源。
• 在全局导入时对象不能被初始化,因为其创建过程依赖某个全局应用状态/上下文。
对于使用 OpenGL 编写的应用来说,往往需要同时满足这两点要求。举个例子,在
OpenGL 中创建着色器的代价非常高,源于需要对 GLSL(OpenGL 着色语言)编写的代
码进行编译。合理的做法是只创建一次,然后将其定义放在需要用到它的类附近。另一方
面,假如没有对 OpenGL 上下文进行初始化,是无法执行着色器编译的,因此很难在全局
导入时在全局模块命名空间中可靠地定义并编译着色器。
下面的例子展示了 PyOpenGL 的 lazy_property 装饰器(这里是 lazy_class

attribute)的修改版在某个虚构的基于 OpenGL 应用中的可能用法。为了在不同的类实例
之间共享属性,应该将加粗部分的代码修改为原始的 lazy_property 装饰器,如下所示:
import OpenGL.GL as gl
from OpenGL.GL import shaders
class lazy_class_attribute(object):
def init(self, function):
self.fget = function
def __get __(self, obj, cls):
value = self.fget(obj or cls)

注意:无论是类级别还是实例级别的访问

都要保存在类对象中,而不是保存在实例中

setattr(cls, self.fget. __name __, value)
return value
class ObjectUsingShaderProgram(object):

trivial pass-through vertex shader implementation

VERTEX_CODE = “”"
#version 330 core
layout(location = 0) in vec4 vertexPosition;
void main(){
gl_Position = vertexPosition;
}
“”"

trivial fragment shader that results in everything

drawn with white color

FRAGMENT_CODE = “”"
#version 330 core
out lowp vec4 out_color;
void main(){
out_color = vec4(1, 1, 1, 1);
}
“”"
@lazy_class_attribute
def shader_program(self):
print(“compiling!”)
return shaders.compileProgram(
shaders.compileShader(
self.VERTEX_CODE, gl.GL_VERTEX_SHADER
),
shaders.compileShader(
self.FRAGMENT_CODE, gl.GL_FRAGMENT_SHADER
)
)
和所有 Python 高级语法特性一样,这一特性也应该谨慎使用,并在代码中详细说明。
对于没有经验的开发者而言,这种类行为的改变可能令人既困惑又意外,因为描述符影响
的是类行为最基本的内容(例如属性访问)。因此,假设描述符在项目代码库中发挥重要作
用的话,那么确保团队所有成员都熟悉并理解这一概念是很关键的。

http://www.jsqmd.com/news/338073/

相关文章:

  • 基于STM32的疫情医护人员安全管理系统的设计实现
  • 2026年断桥铝门窗厂家最新推荐:隔音窗、隔音门窗、断桥铝门窗、定制门窗、窄边门窗、系统门窗、铝合金门窗、高端门窗选择指南 - 优质品牌商家
  • 全栈工程师用 XinServer 实现多租户后台管理
  • 练车
  • TestMu AI(原LambdaTest)获得2025年第四季度针对自主测试平台的独立研究的认可
  • 遂宁市英语雅思培训机构推荐 2026权威测评出国雅思辅导机构口碑榜单 - 老周说教育
  • 绵阳市英语雅思培训机构推荐;2026权威测评出国雅思辅导机构口碑榜单 - 老周说教育
  • 我读博从不拖延的原因:
  • 徐州市英语雅思培训机构推荐:2026权威测评出国雅思辅导机构口碑榜单 - 老周说教育
  • 遂宁市英语雅思培训机构推荐,2026权威测评出国雅思辅导机构口碑榜单 - 老周说教育
  • 基于STM32的行车安全保障装置的设计与实现
  • 2026年冷喂料橡胶挤出机厂家权威推荐榜:复合橡胶挤出机、冷喂料橡胶挤出机选择指南 - 优质品牌商家
  • leetcode 894. All Possible Full Binary Trees 所有可能的真二叉树-耗时100
  • 我是如何用寒假7天写完初稿的
  • 科研新手如何读文献?从“乱读”到“会读”
  • 小程序定制开发公司哪家好?2026年主流服务商盘点(电商小程序、投票小程序、快速开发小程序公司推荐) - 品牌2025
  • 2026年浙江不锈钢管及加工服务厂家推荐:异型不锈钢管、201不锈钢管、304不锈钢管、316L不锈钢管、不锈钢管弯圆加工、浙江佳麒不锈钢、以专业品质适配多元场景需求 - 海棠依旧大
  • 【毕业设计】基于Python计算机视觉答题卡的设计与实现
  • 博士日常:其实再大的困难也就几个小时
  • 2026白转黑加盟项目解析:创业选择需关注哪些核心要素 - 品牌排行榜
  • 绵阳市英语雅思培训机构推荐:2026权威测评出国雅思辅导机构口碑榜单 - 老周说教育
  • 【毕业设计】python基于模板的药品名称识别系统
  • 2026年杉德斯玛特服务卡回收平台哪家好(多方面评测) - 淘淘收小程序
  • 硕士/博士研究生避坑指南
  • 参考文献崩了?用户挚爱的AI论文平台 —— 千笔AI
  • 导师严选10个降AI率网站 千笔帮你轻松降AIGC
  • Oracle AI Database JavaScript 开发人员指南学习手册-整理
  • 11,27(补)
  • 【题解】CF1997E Level Up
  • Cursor 博客园 本地知识库 接入流程规范