一、关于私有关键字
Python中没有private关键字,与之最接近的概念是名称修饰(name mangling)。每当在一个属性前面加上双下划线_ _时,解释器就会立即将其重命名,通过这种方式造成对象实例无法直接访问属性。
class MyClass:
__secret_value=1
二、描述符
描述符descriptor允许你自定义在引用一个对象的属性时应该完成的事情。描述符是python中复杂属性访问的基础。
描述符类基于3个特殊方法,这3个方法组成了描述符协议(descriptor protocol):
1) __set__(self,obj,type=None): 在属性设置时调用 这一方法。
2)__get__(self,obj,value): 在读取属性时调用这一方法。
3)__delete__(self,obj): 对属性调用del时将调用这一方法。
class RevealAccess(object):
"""
A data descriptor that sets and returns values
normally and prints a message logging their access.
"""
def __init__(self, initval=None, name='var'):
self.val = initval
self.name = name
def __get__(self, obj, objtype):
print('Retrieving', self.name)
return self.val
def __set__(self, obj, val):
print('Updating', self.name)
self.val = val
class MyClass(object):
x = RevealAccess(10, 'var "x"')
y = 5
if __name__ == "__main__":
my_instance = MyClass()
# set x attribute (will issue print)
my_instance.x = 4
# access x attribute (will issue print)
assert my_instance.x == 4
# set y attribute (will pass silently)
my_instance.y = 2
# access x attribute (will pass silently)
assert my_instance.y == 2
2.2 property提供了一个内置的描述符类型
class Rectangle:
def __init__(self, x1, y1, x2, y2):
self.x1, self.y1 = x1, y1
self.x2, self.y2 = x2, y2
@property
def width(self):
"""rectangle height measured from top"""
return self.x2 - self.x1
@width.setter
def width(self, value):
self.x2 = self.x1 + value
@property
def height(self):
"""rectangle height measured from top"""
return self.y2 - self.y1
@height.setter
def height(self, value):
self.y2 = self.y1 + value
def __repr__(self):
return "{}({}, {}, {}, {})".format(
self.__class__.__name__,
self.x1, self.y1, self.x2, self.y2
)
if __name__ == "__main__":
rectangle = Rectangle(0, 0, 10, 10)
print(
"At start we have {} with size of {} x {}"
"".format(rectangle, rectangle.width, rectangle.height)
)
rectangle.width = 2
rectangle.height = 8
print(
"After resizing we have {} with size of {} x {}"
"".format(rectangle, rectangle.width, rectangle.height)
)