自定义Python Property装饰器无法设置setter的问题排查
问题原因
你自定义的Property类的__init__方法要求必须传入fget和fset两个参数,但使用@Property装饰getter方法时,只传入了getter函数(fget),没有提供fset,所以触发了参数缺失的错误。
另外,你还需要为Property类实现setter方法,才能让@x.setter语法正常工作——内置的@property正是通过这个方法来绑定setter函数的。
修复后的代码
class Property: def __init__(self, fget=None, fset=None): # 让fset可选,默认值为None self.fget = fget self.fset = fset def __get__(self, obj, objtype=None): if self.fget is None: raise AttributeError("该属性不可读") return self.fget(obj) def __set__(self, obj, value): if self.fset is None: raise AttributeError("该属性不可写") self.fset(obj, value) # 实现setter方法,用于绑定setter函数 def setter(self, fset): # 返回一个新的Property实例,复用当前的fget,传入新的fset return Property(self.fget, fset) class X: def __init__(self, val): self.__x = val @Property def x(self): return self.__x @x.setter def x(self, val): self.__x = int(val) myx = X(13) print(myx.x) # 输出13 myx.x = "25" print(myx.x) # 输出25
关键修改点
- 给
Property.__init__的fset参数设置默认值None,这样装饰getter时无需传入第二个参数。 - 添加
setter方法:该方法接收setter函数,返回一个新的Property实例,将原有getter和新的setter绑定在一起,这是@x.setter语法生效的核心。 - 在
__get__和__set__中增加判断,当对应的方法未设置时抛出AttributeError,模拟内置property的只读/只写行为。
内容的提问来源于stack exchange,提问作者forstack overflowizi
相关产品推荐
相关产品推荐

