发布于2024-11-25 16:41 阅读(720) 评论(0) 点赞(7) 收藏(4)
我一直在重构一个用于将文本传送到屏幕上的文本类。我最近了解了@property
装饰器,并认为在这个类中使用它会有所帮助。
这是我正在编写的代码的精简版本:
class Text:
def __init__(self, text, antialias):
self.text = text
self.antialias = antialias
self._render_text()
@property
def text(self):
return self._text
@text.setter
def text(self, value):
self._text = value
self._requires_render = True
@property
def antialias(self):
return self._antialias
@antialias.setter
def antialias(self, value):
self._antialias = value
self._requires_render = True
def _render_text(self):
self._required_render = False
def blit(self):
if self._requires_render:
self._render_text()
# blit text to screen
我注意到我使用 setter 和 getter 的主要动机是更改一个属性,该属性在将文本传送到屏幕之前命令重新渲染文本。这确保了更改文本对象的属性在事件循环中正确更新。它还确保如果连续调用多个需要重新渲染文本的属性,则只会触发一次重新渲染,因为重新渲染检查在每个游戏循环中只发生一次。
然而,这似乎也有些过度,我想知道是否有办法编写一个@property
包含该self._requires_render
行的自定义对象。虽然经过一番搜索,没有发现任何人遇到同样的问题,但我还是认为我的逻辑可能有缺陷,并且有一种更简单的方法来检测对象的属性何时更新,并运行一些代码。
是的 - 理想的情况是使用与其property
自身相同的机制 - 但财产并不是理想的。
Python 中的和常规方法都property
使用所谓的descriptor
协议——这意味着类中关联的属性可以具有__get__
和__set__
方法,它们用于在使用符号访问值时.
。
基本上,您所需要的只是一个__set__
设置_requires_render
属性的方法,否则将允许透明地访问该属性。您可以利用__set_name__
与描述符协议相关联的方法,该方法在类创建时由语言调用:
class RenderNeeded:
def __set_name__(self, owner, name):
self.name = name
def __get__(self, instance, owner):
if instance is None:
return self
return instance.__dict__[self.name]
def __set__(self, instance, value):
instance._requires_render = True
instance.__dict__[self.name] = value
from functools import wraps
# and for methods instead of variables,
# this is the decorator approach:
def clear_rendering(func):
@wraps(func)
def wrapper(self, *args, **kw):
result = func(self, *args, **kw)
self._requires_render = False
return result
return wrapper
class Text:
def __init__(...):
...
text = RenderNeeded()
antialias = RenderNeeded()
@clear_rendering
def blit(self, ...):
# blit text code ...
...
除了创建自定义描述符之外的另一种方法是__setattr__
直接在类中自定义方法:
class Text:
def __init__(self, text, antialias):
...
def __setattr__(self, attr, value):
if attr in {"text", "antialias", ...}:
# this triggers a recursive call, but there is no problem. Just use `super().__setattr__` to avoid it, if preferred:
self._requires_render = True
return super().__setattr__(attr, value)
作者:黑洞官方问答小能手
链接:https://www.pythonheidong.com/blog/article/2045893/ad1e7b0456e96ace7aee/
来源:python黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!