封装的理解
封装Encapsulation:属性和方法的抽象
-
属性的抽象:对类的属性(变量)进行定义、隔离及保护
-
方法的抽象:对类的方法(函数)进行定义、隔离及保护
-
目标是形成一个类对外可操作属性和方法的接口
-
属性
- 私有属性:只能在类内部访问
- 公开属性:可以通过类/对象名访问
-
方法
- 私有方法:只能在类内部使用
- 公开方法:可以通过类/对象名访问
私有类属性
- 仅供当前类访问的类属性,子类亦不能访问
区别:私有类属性名开始需要有两个下划线(__), 如__countclass <类名>: <私有属性名> = <类属性初值> def __init__(self, <参数列表>) ...
- 只能在类内部被方法所访问
- 不能通过<类名>.<属性名>或<对象名>.<属性名>方式访问
- 有效保证了属性维护的可控性
class DemoClass: __count = 0 def __init__(self, name): self.name = name DemoClass.__count += 1 @classmethod def getCount(cls): return DemoClass.__count dc1 = DemoClass('老王') dc2 = DemoClass('老李') print(DemoClass.getCount()) print(DemoClass.__count)
输出
2
AttributeError:type object '‘DemoClass’ has no attribute ‘__count’
私有实例属性
- 仅供当前类内部访问的实例属性,子类亦不能访问
class <类名>: <类属性名> = <类属性初值> def __init__(self, <参数列表>) self.<实例属性名> = <实例属性初值> ...
区别:私有属性名开始需要有两个下划线(__),如__name
- 只能在类内部被方法所访问
- 不能通过<类名>.<属性名>或<对象名>.<属性名>方式访问
- 有效保证了属性维护的可控性
class DemoClass:
def __init__(self, name):
self.__name = name
def getName(self):
return self.__name
dc1 = DemoClass("老王")
dc2 = DemoClass("老李")
print(dc1.getName(), dc2.getName())
print(dc1.__name, dc2.__name)
输出
老王 老李
AttributeError:‘DemoClass’ object has no attribute '__name
注意
双下划线方法只是一种转换约定,转换后,类内原有名字发生了变化,这是一种形式上的私有。Python设计逻辑不明确支持私有。我们可以通过dc1._DemoClass__name
来访问私有属性。
私有方法
- 类内部定义并使用的函数
私有方法名开始需要有两个下划线(__),如__getCount()class <类名>: def <方法名>(self, <参数列表>) ...
class DemoClass: def __init__(self, name): self.__name = name def __getName(self): if self.__name != "": return self.__name else: return "老张" def printName(self): return "{}同志".format(self.__getName()) dc1 = DemoClass("老王") dc2 = DemoClass("") print(dc1.printName(), dc2.printName())
输出
老王同志 老张同志
类的保留属性
-
Python解释器预留的类属性,以双下划綫开头和结尾
- 也叫:特殊属性,Special Attributes
- 特点:双下划线开头和结尾
- 作用:为理解Python类提供了统一的属性接口
- 属性值:具有特定含义,类定义后直接使用
-
仅用<类名>访问的保留属性
__name__
:类的名称__qualname__
:以.分隔从模块全局命名空间开始的类名称__bases__
:类所继承的基类名称
class DemoClass: "A Demo Class" def __init__(self, name): self.name = name def getName(self): return self.name dc1 = DemoClass("老王") print(DemoClass.__qualname__, DemoClass.__name__, DemoClass.__bases__)
输出
DemoClass DemoClass (<class ‘object’>,)
<类>.__dict__
包含类成员信息的字典,key是属性和方法名称,value是地址<对象>.__dict__
包含对象属性信息的字典,key是属性名称,value是值__class__
对象所对应的类信息,即type信息__doc__
类描述,写在类定义下的首行字符串,不能继承__module__
类所在模块的名称
class DemoClass: "A Demo Class" def __init__(self, name): self.name = name def getName(self): return self.name dc1 = DemoClass("老王") print(DemoClass.__doc__, DemoClass.__module__, DemoClass.__class__) print(dc1.__doc__, dc1.__module__, dc1.__class__)
输出
A Demo Class
__main__
<class ‘type’>
A Demo Class__main__
<class ‘__main__
.DemoClass’>
类的保留方法
- Python解释器预留的类方法,以双下划线开头和结尾
- 也叫:特殊方法,Special Methods
- 特点:双下划线开头和结尾
- 作用:为操作Python类提供了统一的方法接口
- 方法逻辑:具有特定含义,一般与操作符关联,类定义需要重载
- 常用保留方法:基础类别
保留方法 | 对应操作 | 描述 |
---|---|---|
obj.__init__() | obj=ClassName() | 初始化实例对象的函数逻辑 |
obj.__del__() | del obj | 删除实例对象的函数逻辑 |
obj.__repr__() | repr(obj) | 定义对象可打印字符串的函数逻辑 |
obj.__str__() | str(obj) | 定义对象字符串转换操作的函数逻辑 |
obj.__len__() | len(obj) | 定义对象长度操作的函数逻辑 |
obj.__reversed__() | obj.reversed() | 定义对象逆序的函数逻辑 |
obj.__abs__() | abs(obj) | 定义对象绝对值操作的函数逻辑 |
obj.__int__() | int(obj) | 定义对象整数转换的函数逻辑 |
obj.__lt__() obj.__le__() obj.__eq__() obj.__ne__() obj.__gt__() obj.__ge__() | obj1 < obj2 obj1 <= obj2 obj1 == obj2 obj1 != obj2 obj1 > obj2 obj1 >= obj2 | 对象间比较操作的保留方法 |