使用@property将类方法包装为属性

@property 是 Python 里的装饰器 ,核心作用是:把类的「方法」伪装成「普通属性」,像调用属性一样调用方法,还能安全控制属性的访问和修改。

核心作用

  1. 简化调用:调用方法时不用加括号,像访问属性一样直接用
  2. 安全管控:可以隐藏内部属性,限制属性的修改规则
  3. 只读属性 :只定义 @property,不写修改方法,属性就无法被赋值

极简示例

python 复制代码
class Person:
    def __init__(self, name):
        self._name = name  # 下划线表示内部私有属性

    @property  # 装饰器:把方法变成属性
    def name(self):
        # 读取属性时自动执行
        return self._name

# 调用方式(像属性一样,不用加())
p = Person("小明")
print(p.name)  # 输出:小明
# p.name = "小红"  # 报错!只读属性,无法修改

进阶:可修改的属性

搭配 @属性名.setter,就能安全控制修改逻辑:

python 复制代码
class Person:
    def __init__(self, name):
        self._name = name  # 下划线表示内部私有属性

    @property  # 装饰器:把方法变成属性
    def name(self):
        # 读取属性时自动执行
        return self._name

    @name.setter
    def name(self, value):
        # 写入属性时自动执行
        self._name = value

# 调用方式(像属性一样,不用加())
p = Person("小明")
print(p.name)  # 输出:小明
p.name = "小红"  # 设置属性值
print(p.name)  # 输出:小红

总结

  1. @property → 定义读取方法(getter),并伪装成属性
  2. @属性名.setter → 定义修改方法(加校验 / 限制)
  3. 好处:代码简洁、安全可控、符合 Python 优雅的语法风格
  4. 名字必须一样
  5. 只有 @property 时,属性是只读

在QtPy中的应用

定义一个hmi变量,并绑定变量和槽函数,当变量变化时发射信号,执行槽函数。
python 复制代码
import sys

from PySide6.QtCore import QObject, Signal
from PySide6.QtWidgets import QApplication, QPushButton


class HmiVar(QObject):
    valueChanged = Signal(object)
    def __init__(self, var_name, addr, data_type, init_val=None):
        super().__init__()
        self._var_name = var_name    # 变量名
        self._addr = addr            # PLC地址:如 "M0.0" "DB1.DBW0"
        self._data_type = data_type  # bool / int / real
        self._value = init_val

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, v):
        if self._value != v:
            self._value = v
            self.valueChanged.emit(v)

    def set_val(self, v):
        self.value = v

# 绑定变量到槽函数
def bind_var(var: HmiVar, slot):
    var.valueChanged.connect(slot)

var1 = HmiVar("油泵运行", "M0.0", "bool")
bind_var(var1, lambda v: print(f"油泵运行变为: {v}"))

app = QApplication(sys.argv)
btn_start = QPushButton("油泵启/停")
btn_start.clicked.connect(lambda: var1.set_val(not var1.value))
btn_start.show()

app.exec()
相关推荐
江畔柳前堤5 小时前
roLabelImg 详细安装教程
开发语言·人工智能·后端·云原生
0566466 小时前
agent学习Day15——SQLAlchemy 查询过滤、分页与历史列表接口
python·学习·fastapi
Wang's Blog6 小时前
Go-Zero 项目开发47:自研微服务框架的必要性与核心结构设计
开发语言·微服务·golang
白鸽(二般)6 小时前
MinIO Java Client API
java·开发语言
hPw0eKIqD6 小时前
C++ 模板参数推导问题小记(非推导上下文)
开发语言·c++
程序员爱德华7 小时前
Python与C++:异同点对比
c++·python
hangyuekejiGEO7 小时前
GEO技术服务选型指南
大数据·人工智能·python
临床数据科学和人工智能兴趣组7 小时前
要使用 R Markdown,首先需要安装 R 和 RStudio,接着安装 rmarkdown 包
开发语言·数据挖掘·数据分析·r语言·r语言-4.2.1
软萌萌的17 小时前
Java Spring Boot 修改yml配置&加载顺序规则
java·spring boot·python
Nebula嵌入式7 小时前
【C语言】09-深入解析main函数
linux·c语言·开发语言·嵌入式