-- TOC --
python对象本质上是没有私有成员的,用双下划线的方式定义的成员,也可以通过附加类名的方式来访问。不过,这种奇怪的访问方式在编写代码的时候,应该是要被禁止的。
使用一个下划线来暗示这是私有成员,也是一种方法,不过没有强制力,修改的时候,也没有任何约束力。python提供了一个@property
装饰器,可以更好的控制对象成员的访问和修改。
下面的代码示例,用@property修饰一个成员函数,将其变成一个成员变量来访问:
class test():
def __init__(self):
self.__foo = 'foo'
self.__bar = 'bar'
@property
def foo(self):
# print('running in foo function')
return self.__foo
t = test()
print(t.foo)
用@property装饰的foo函数,就变成了foo成员变量
,访问这个成员变量的时候,触发内部的一个函数执行。此时,foo这个成员变量只能读,不能写,如果尝试使用t.foo=123来赋值,会出现错误:AttributeError: can't set attribute。
下面的代码示例,实现修改内部__foo成员的功能:
class test():
def __init__(self):
self.__foo = 'foo'
self.__bar = 'bar'
@property
def foo(self):
# print('running in foo function')
return self.__foo
@foo.setter
def foo(self, foo_value):
if foo_value < 100:
pass
else:
self.__foo = foo_value
t = test()
print(t.foo)
t.foo = 123
print(t.foo)
注意@foo.setter
这个装饰器的由来。在设置的时候,外部代码还是简简单单地使用等号实现,而触发的是内部的一段代码,这段代码可以实现设置前的检查!
下面的代码,实现对某个成员的删除控制:
class test():
def __init__(self):
self.__foo = 'foo'
self.__bar = 'bar'
@property
def foo(self):
# print('running in foo function')
return self.__foo
@foo.setter
def foo(self, foo_value):
if foo_value < 100:
pass
else:
self.__foo = foo_value
@foo.deleter
def foo(self):
if self.__foo > 200:
self.__foo = 200
t = test()
print(t.foo)
t.foo = 123
print(t.foo)
t.foo = 234
print(t.foo)
del t.foo
print(t.foo)
注意@foo.deleter
这个装饰器。
执行del t.foo语句的时候,同样触发一段自定义代码,上面的代码示例,并没有真正删除foo这个变量,只是限制它的值。
被@foo.setter和被@foo.deleter装饰的成员函数名称,都必须是foo。
通过@property装饰器,以及其衍生出来的一些其它装饰器,我们可以通过简单的语义实现复杂的功能,可以增加代码的可读性。
@property装饰后的属性,可以被继承
:
class aaa():
def __init__(self):
self.a = 1
@property
def geta(self):
return self.a
@geta.setter
def geta(self, value):
self.a = value
class bbb(aaa):
pass
ina = aaa()
print(ina.geta)
ina.geta = 2
print(ina.geta)
inb = bbb()
print(inb.geta)
inb.geta = 3
print(inb.geta)
可以被继承这一点,我以前不是特别理解,现在已经理解,并且觉得都不需要在笔记中写出来。
本文链接:https://cs.pynote.net/sf/python/202203211/
-- EOF --
-- MORE --