Python笔记之Python中的`@`装饰器总结笔记
Python笔记之Python中的@
装饰器总结笔记
参考笔记
1.Python笔记之getattr
和hasattr
用法详解
2.Python笔记之Python中的@
装饰器总结笔记
code review!
文章目录
- Python笔记之Python中的`@`装饰器总结笔记
- 1.基础:`@` 作为函数装饰器
- 1.1 示例:使用 `@`
- 1.2 示例:不用 `@` 的等价写法
- 2.内置装饰器:`@property`
- 2.1 示例:使用 `@property`
- 2.2 示例:不用 `@property` 的写法
- 2.3 进阶:getter / setter / deleter
- 3.Qt for Python (PySide6) 的 `Property`
- 3.1 基本示例
- 3.2 参数常用说明
- 3.3 结合 QML 示例
- 4.总结对照表
1.基础:@
作为函数装饰器
装饰器本质上是一个函数,它接收另一个函数作为参数,返回一个“增强后的函数”。
写法上,@decorator
就是 func = decorator(func)
的语法糖。
1.1 示例:使用 @
def my_decorator(func):def wrapper():print("执行前")func()print("执行后")return wrapper@my_decorator
def say_hello():print("Hello Python!")say_hello()
输出:
执行前
Hello Python!
执行后
1.2 示例:不用 @
的等价写法
def my_decorator(func):def wrapper():print("执行前")func()print("执行后")return wrapperdef say_hello():print("Hello Python!")say_hello = my_decorator(say_hello)
say_hello()
输出:
执行前
Hello Python!
执行后
结论:
@decorator
==func = decorator(func)
- 推荐写法是直接用
@
,更简洁、更直观。
2.内置装饰器:@property
@property
可以把一个方法伪装成 只读属性,让调用更自然。
还可以配合 @<property>.setter
/ @<property>.deleter
受控管理属性。
2.1 示例:使用 @property
class Person:def __init__(self, name, birth_year):self.name = nameself.birth_year = birth_year@propertydef age(self): # getterreturn 2025 - self.birth_yearp = Person("Alice", 2000)
print(p.name) # 普通属性
print(p.age) # 不用写 (),看起来是个属性
输出:
Alice
25
2.2 示例:不用 @property
的写法
class Person:def __init__(self, name, birth_year):self.name = nameself.birth_year = birth_yeardef age(self): # 普通方法return 2025 - self.birth_yearp = Person("Alice", 2000)
print(p.name)
print(p.age()) # 必须写 ()
输出:
Alice
25
对比总结:
写法 | 调用方式 | 特点 |
---|---|---|
@property | p.age | 更像属性,语义清晰 |
普通方法 | p.age() | 显式调用,方法风格 |
2.3 进阶:getter / setter / deleter
class Person:def __init__(self, age):self._age = age@propertydef age(self): # getterreturn self._age@age.setterdef age(self, value): # setterif value < 0:raise ValueError("年龄不能是负数")self._age = value@age.deleterdef age(self): # deleterprint("删除 age 属性")del self._agep = Person(20)
print(p.age) # -> 20
p.age = 25 # 调用 setter
print(p.age) # -> 25
del p.age # 调用 deleter
3.Qt for Python (PySide6) 的 Property
在 PySide6 里有专门的 PySide6.QtCore.Property
,它与 Python 的 @property
类似,但它 额外集成了 Qt 的元对象系统,使得属性可以在 QML、信号槽、动画、绑定 中工作。
3.1 基本示例
from PySide6.QtCore import QObject, Property, Signalclass Person(QObject):def __init__(self, name="", parent=None):super().__init__(parent)self._name = namenameChanged = Signal() # 属性变更信号def getName(self): # getterreturn self._namedef setName(self, value): # setterif self._name != value:self._name = valueself.nameChanged.emit()name = Property(str, fget=getName, fset=setName, notify=nameChanged)
使用:
p = Person("Alice")
print(p.name) # -> Alice
p.name = "Bob" # setter 会触发 nameChanged 信号
3.2 参数常用说明
Property(type, fget=None, fset=None, notify=None, constant=False, final=False, ...)
- type: 属性的数据类型(如
str
,int
)。 - fget: getter 方法。
- fset: setter 方法(不写则为只读)。
- notify: 属性值改变时触发的信号(在 QML 中绑定必需)。
- constant: 常量属性,不可修改。
- final: 最终属性,子类不可重写。
3.3 结合 QML 示例
from PySide6.QtCore import QObject, Property, Signal
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtWidgets import QApplication
import sysclass Counter(QObject):valueChanged = Signal()def __init__(self):super().__init__()self._value = 0def getValue(self):return self._valuedef setValue(self, v):if self._value != v:self._value = vself.valueChanged.emit()value = Property(int, fget=getValue, fset=setValue, notify=valueChanged)if __name__ == "__main__":app = QApplication(sys.argv)engine = QQmlApplicationEngine()counter = Counter()engine.rootContext().setContextProperty("counter", counter)engine.load("main.qml")sys.exit(app.exec())
QML 中:
Text {text: "Counter: " + counter.value
}
当 Python 发射 valueChanged
信号时,QML 界面会自动更新。
4.总结对照表
装饰器 | 作用范围 | 特点 |
---|---|---|
自定义函数装饰器 | 普通函数/方法 | 在调用前后插入额外逻辑 |
@property | Python 类属性 | 让方法像属性一样访问,可加 setter/deleter 受控管理 |
PySide6.Property | Qt (QObject 子类) 属性 | 与 Qt 元对象系统集成,支持 QML 绑定 / 信号通知 |