Python 封装技术是一种面向对象编程的重要概念,它允许将数据和相关操作封装在一个单独的单元中,以实现代码的重用和数据保护。主要内容如下:
- 属性
- 访问权限
- 方法
- 魔术方法
1. 属性
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) # 注意: 当实例属性、类属性名冲突时,通过实例属性优先访问实例属性
2. 访问权限
在很多支持面向对象技术的语言中,一般都会提供类似 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)
3. 方法
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()
4. 魔术方法
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)