给定以下课程,我可以使用 setter/getter 构造修改
_x
。但是现在可以通过调用方法来改变_x
吗?
我问的原因只是因为以后使用
lambda y: (c.x := y)
将某些东西定义为 lambda 会非常方便,它在 3.8 中有效,但在 3.7 中我们需要像 lambda y: c.x.some_method_maybe(y)
这样的东西。
class C:
def __init__(self):
self._x = 0
@property
def x(self):
return self._x
@x.setter
def x(self,_x):
print(_x)
self._x = _x
c = C()
c.x = 999 # this works
c.x.some_method_maybe(999) # call setter of x explicitly?
您可以将 getter 和 setter 设置为普通方法,然后将它们打包到属性中
class C:
def __init__(self):
self._x = 0
def get_x(self):
"getter for property x, see `help(C.x)`"
return self._x
def set_x(self,_x):
"setter for property x, see `help(C.x)`"
print(_x)
self._x = _x
x = property(get_x,set_x, doc="""\
documentation of property x here,
`help(C.x)` will print this""")
然后您可以使用
c.set_x
作为回调,并且属性 c.x
仍然按您的预期工作。
但请注意,该方法完全允许执行
self._x = _x
操作,因为它是一个函数而不是 lambda,因此您可以在需要回调的地方执行相同的操作:
def modify(y): c.x = y
只要您可以在自己的行上定义 lambda,这始终是一个有效的设计模式,只需为您的回调声明一个短函数。
或者,如果您喜欢一个衬垫和 lambda 并且讨厌可读性,如果您不想直接公开 setter,则可以在类本身上使用属性的
__set__
魔术方法。
modify = lambda val: type(c).x.__set__(c, val)
其中
type(c)
获取类对象,.x
直接给出属性对象,.__set__
是当您设置实例的属性时调用的魔术方法,并且您可以将实例作为第一个参数来调用它d 希望调用类上的方法能够工作。