第7章 面向对象程序设计
- 7.1 面向对象概述
- 7.2 类的定义
- 7.3 类的实例化
- 7.4 访问限制
- 7.5 继承
- 7.6 封装
- 7.7 多态
- 7.8 装饰器
- 7.9 特殊方法
7.4 访问限制
单下划线开头:以单下划线开头(`_foo`)的代表不能直接访问的类属性,需通过类提供的接口进行访问,也不能以`from xxx import *`导入;
双下划线开头:以双下划线开头的(`__foo`)代表类的私有成员;
首尾双下划线:以双下划线开头和结尾的`__foo__`代表python里特殊方法专用的标识,如`__init__()` 代表类的构造函数
单下划线开头
以一个下划线开头的成员名,比如_name,可以被外部访问,但是,请把我视为私有成员,不要在外部访问我!
双下划线开头
# 实例属性并未限制时,外部是可以自由访问修改的
class Rectangle():
def __init__(self, length, width):
self.length = length # 实例属性
self.width = width
def getPeri(self):
peri = (self.length + self.width) * 2
return peri
def getArea(self):
area = self.length * self.width
return area
# 修改实例属性值
rect = Rectangle(3, 4) # 实例化
rect.length = 10
rect.width = 5
print(rect.length, rect.width) # 对象名.属性名
output:
10 5
# 将实例属性定义为私有变量,变量名以双下划线开头,实例化后外部是不可以访问的
class Rectangle():
def __init__(self, length, width):
self.__length = length # 实例属性名为__length
self.__width = width
def getPeri(self):
peri = (self.__length + self.__width) * 2 # 方法中相应的修改引用
return peri
def getArea(self):
area = self.__length * self.__width
return area
rect = Rectangle(3, 4) # 实例化
print(rect.__length, rect.__width)
output:
AttributeError: 'Rectangle' object has no attribute '__length'
如果外部代码必须要获取__length
和__width
怎么办?可以给类增加相应的方法:
# 将实例属性定义为私有变量,变量名以双下划线开头,实例化后外部是不可以访问的,可提供相应的方法供外部访问
class Rectangle():
def __init__(self, length, width):
self.__length = length
self.__width = width
def getPeri(self):
peri = (self.__length + self.__width) * 2
return peri
def getArea(self):
area = self.__length * self.__width
return area
def get_length(self): # 获取实例属性__length的方法
return self.__length
def get_width(self): # 获取实例属性__width的方法
return self.__width
rect = Rectangle(3, 4) # 实例化
print(rect.get_length(), rect.get_width())
output:
3 4
首尾双下划线开头
定义:首尾双下划线方法是特殊方法,他是解释器提供的,由双下划线加方法名加双下划线,方法名的具有特殊意义的方法,首尾双下划线方法主要是python源码程序员使用的,我们在开发中尽量不要使用双下方法,但是深入研究双下方法,更有益于我们阅读源码。
# __len__方法,调用len函数会触发__len__方法
class A:
def __init__(self):
self.a = 1
self.b = 2
def __len__(self):
return len(self.__dict__)
a = A()
print(a.__dict__)
print(len(a))
output:
{'a': 1, 'b': 2}
2
# __hash__方法
class A:
def __init__(self):
self.a = 1
self.b = 2
def __hash__(self):
return hash(str(self.a)+str(self.b))
a = A()
print(hash(a))
output:
8401973186519088369
# __str__方法
class A:
def __init__(self):
pass
def __str__(self):
return '蚂蚁大宝卡'
a = A()
print(a)
print('%s' % a)
output:
蚂蚁大宝卡
蚂蚁大宝卡
# __call__
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print('__call__')
obj = Foo() # 执行 __init__
obj() # 执行 __call__
output:
__call__