Python 封装技术是一种面向对象编程的重要概念,它允许将数据和相关操作封装在一个单独的单元中,以实现代码的重用和数据保护。主要内容如下:
-
属性
-
访问权限
-
方法
-
魔术方法
-
属性 {#title-0} ================
Python 中的属性表示在类中定义的数据变量,它共有两种类型的属性:类属性、实例属性。类属性是所有该类型实例对象共享,而实例属性只归属于实例对象。
# 1. 实例属性
class Demo:
# 构造函数
def __init__(self):
# 初始化时绑定实例属性
self.v1 = 200
demo = Demo()
demo.v2 = 300 # 使用时按需绑定实例属性
print(demo.v1, demo.v2)
# 2. 类属性
class Test:
# 初始化类时绑定类属性
v1 = 300
# 使用时按需绑定类属性
Test.v2 = 400
t1 = Test()
t2 = Test()
print(t1.v1, t2.v1, Test.v1)
print(t1.v2, t2.v2, Test.v2)
# t2.v1 = 600 # 注意, 这是绑定实例属性,并不是修改类属性
Test.v2 = 500 # 通过类名访问才能修改
print('-' * 20)
print(t1.v1, t2.v1, Test.v1)
print(t1.v2, t2.v2, Test.v2)
# 注意: 当实例属性、类属性名冲突时,通过实例属性优先访问实例属性
- 访问权限 {#title-1} ==================
在很多支持面向对象技术的语言中,一般都会提供类似 public、protected、private 关键字来设定成员的访问权限。而在 Python, 访问权限主要是一种命名约定,而不是强制执行。即使是私有成员,仍然可以通过特定的命名规则进行访问。具体来说,可以使用以下规则来访问私有成员:
- 公有访问权限:一般没有特殊的修饰方式
- 保护访问权限:属性名使用单下划线开头
- 私有访问权限:属性名使用双下划线开头
另外,需要注意的是,无论是类属性还是实例属性都可以拥有访问控制权限。
class Demo:
# 类属性
public_v1 = 100
_protected_v1 = 200
__private_v1 = 300
def __init__(self):
# 实例属性
self.public_v2 = 100
self._protected_v2 = 200
self.__private_v2 = 300
demo = Demo()
# 访问不同权限成员
print(demo.public_v2)
print(demo._protected_v2)
print(demo._Demo__private_v2)
- 方法 {#title-2} ================
Python 类中定义的方法分为三种:
- 类方法
- 实例方法
- 静态方法
类方法用于封装类属性,实例方法用于封装实例属性,静态方法则是类作用域的普通方法。
class Demo:
# 类属性
__v1 = 100
def __init__(self):
self.__v2 = 200
# 实例方法
def set_v2(self, value):
self.__v2 = value
def get_v2(self):
return self.__v2
# 类方法
@classmethod
def set_v1(cls, value):
cls.__v1 = value
@classmethod
def get_v1(cls):
return cls.__v1
# 静态方法
@staticmethod
def my_function():
print('静态方法只能访问类属性', Demo.__v1)
# 1. 类方法调用
print(Demo.get_v1())
Demo.set_v1(200)
print(Demo.get_v1())
# 2. 实例方法调用
demo = Demo()
print(demo.get_v2())
demo.set_v2(300)
print(demo.get_v2())
# 3. 静态方法调用
demo.my_function()
Demo.my_function()
- 魔术方法 {#title-3} ==================
Python 中的魔术方法(Magic Methods),魔术方法有两个特点:
- 大多常用的魔术方法以两个下划线开始、两个下划线结束
- 魔术方法用于实现对象的特定行为和操作
下面给出常用魔术方法的使用示例:
class Demo:
# 类属性
__v1 = 100
# 1. 构建对象时自动调用
def __init__(self):
print('初始化操作')
# 2. 使用print函数时自动调用,必须返回字符串
def __str__(self):
return 'abc'
# 3. 使用len函数时自动调用,必须返回整型
def __len__(self):
return 100
# 4. 使用下标语法,返回任意类型
def __getitem__(self, item):
return 'hello world'
# 5. 对象使用+运算符时调用,返回任意类型
def __add__(self, other):
return 666
# 6. 对象使用<运算符时调用,返回任意类型
def __lt__(self, other):
return True
demo1 = Demo()
print(demo1)
print(len(demo1))
print(demo1[0], demo1[9999])
demo2 = Demo()
print(demo1 + demo2)
print(demo1 < demo2)
# 虽然未增加 >、== 运算符对应的魔术方法,Python 可由<运算符推断出来
# 但是如果只增加==运算符,<、> 是无法进行比较
print(demo1 > demo2)
print(demo1 == demo2)