LLM系列:1.python入门:11.类与对象(Class & Object)
类与对象(Class & Object)
一. 面向对象与类的基础
类(Class)是封装对象属性和行为的载体,具有相同属性和行为的一类实体被称为类。
==在 Python 中“一切皆对象”,每个对象都有其独立的身份(id() 返回内存地址)、类型(type())和值(内容)。==对象与类的关系,即具体实例与抽象类型之间的关系。
二. 访问权限与成员保护
Python 并没有 C++ 那种强制性的 public、private 关键字,它通过 命名规范 来约定访问权限。
1. 公有成员(Public)
特征: 无前置下划线(如 name, func())。
权限: 类内部、子类内部以及外部均可自由访问。
2. 受保护成员(Protected)
特征: 单下划线开头(如 _age, _func())。
权限: 虽然技术上在外部仍能访问,但 Python 约定这属于内部属性,不建议外部直接调用。
3. 私有成员(Private)
对应 C++: private
特征: 双下划线开头,且无结尾下划线(如 __id, __func())。
权限: 仅限类内部访问。Python 会对其进行“名称修饰”,外部无法直接通过原名访问;但继承的类也可以通过self.__xx访问,但不能直接访问。
4. 特殊方法/魔法方法(Dunder Methods)
特征: 开头和结尾都有双下划线(如 __init__, __str__)。
注意: 它们是系统预留的特殊接口,及:公有的;但系统自动调用,不会手动调用。
(1).对象创建/初始化
| 方法 | 触发时机 |
|---|---|
__new__ |
创建对象时(较少直接用) |
__init__ |
初始化对象时自动调用 |
(2).字符串/输出
| 方法 | 触发时机 |
|---|---|
__str__ |
print(obj) 时调用(给用户看) |
__repr__ |
repr(obj) / 调试时调用(给开发者看) |
(3).容器相关
| 方法 | 触发时机 |
|---|---|
__len__ |
len(obj) |
__getitem__ |
obj[key] |
__setitem__ |
obj[key] = value |
__delitem__ |
del obj[key] |
__iter__ |
for 循环遍历 |
__contains__ |
item in obj |
(4).运算符重载
| 方法 | 触发时机 |
|---|---|
__add__ |
+ |
__sub__ |
- |
__mul__ |
* |
__truediv__ |
/ |
__eq__ |
== |
__lt__ |
< |
(5).类型转换
| 方法 | 触发时机 |
|---|---|
__int__ |
int(obj) |
__float__ |
float(obj) |
__str__ |
str(obj) |
__bool__ |
bool(obj) |
(6).属性访问
| 方法 | 触发时机 |
|---|---|
__getattr__ |
访问不存在属性 |
__setattr__ |
设置属性 |
__delattr__ |
删除属性 |
(7).可调用对象
| 方法 | 触发时机 |
|---|---|
__call__ |
对象像函数一样调用 |
(8).上下文管理
| 方法 | 触发时机 |
|---|---|
__enter__ |
with 进入 |
__exit__ |
with 结束 |
三. 成员变量 (数据成员)
在 Python 中,成员变量根据其作用域和初始化时机分为 类属性(静态成员变量) 和 实例属性(普通成员变量)。
1. 类属性 (静态成员变量)
作用: 属于类本身,被该类的所有对象共享。在内存中只存在一份,类似于 C++ 的 static 成员。
- 初始化时机: 类定义时立即初始化(在代码执行到
class语句块时)。 - 如何初始化: 直接在类体中、函数体外进行赋值。
- 访问方式: 推荐使用
类名.属性名访问,也可以通过实例.属性名访问。
class Human:
mam = True # 公有类属性(静态成员)
_category = "Mammal" # 受保护类属性
__logic_gate = True # 私有类属性
2. 实例属性 (普通成员变量)
作用: 属于具体的对象实例。每个对象都拥有一份独立的拷贝,互不影响。
- 初始化时机: 实例化对象时初始化。
- 如何初始化: 通常在构造函数
__init__中,通过self.属性名 = 值进行赋值。
class Human:
def __init__(self, name, secret):
self.name = name # 公有实例属性
self.__secret = secret # 私有实例属性:外部无法直接通过 zs.__secret 访问
四. 成员函数 (方法)
1. 实例方法 (普通成员函数)
作用: 最常用的方法。可以访问实例属性和类属性。
- 格式: 第一个参数必须是
self(代表当前对象实例)。 - 私有化: 若方法名以
__开头,则变为私有方法,外部不可见;继承的子类可以通过self.xx访问,但不能直接访问
2. 类方法 (Class Method)
作用: 类似于 C++ 的静态成员函数,但它能感知到类本身。
- 格式: 使用
@classmethod装饰,第一个参数必须是cls(代表类本身)。
3. 静态方法 (Static Method)
作用: 纯粹的工具函数。既不访问 self 也不访问 cls。
- 格式: 使用
@staticmethod装饰。
五. 构造函数与初始化细节
1. __init__ - 构造函数
作用: 在类被实例化创建对象时由系统自动调用,用于执行“普通成员变量”的初始化。
参数说明:
- self (实例本身):类似于 C++ 中的
this指针。- 自动传入: 调用时不需要手动传递,Python 会自动将当前创建的对象绑定到
self上。 - 必须存在: 必须作为所有实例方法的第一个参数。
- 自动传入: 调用时不需要手动传递,Python 会自动将当前创建的对象绑定到
返回值:
- NoneType: 构造函数不能有返回值(固定返回
None)。
六. 封装、继承与高级应用
1. @property - 属性封装
作用: 将一个方法伪装成“成员变量”。常用于实现只读变量或对私有变量进行受控读取。
class Human:
def __init__(self, secret):
self.__secret = secret # 私有变量
@property
def secret(self):
# 外部可以通过 zs.secret 读取,但无法直接修改
return self.__secret
2. 类的继承
作用: 子类完全继承父类的所有公有和受保护属性和方法。子类可以重写(Override)父类的方法。
- 注意: 子类不能直接访问父类的私有成员 (
__xx),但可以通过self.__xx访问。
3. 子类显式调用父类构造函数
作用: 在 Python 中,如果子类定义了自己的 __init__ 方法,父类的 __init__ 不会被自动调用。若需在子类中使用父类的初始化逻辑,必须显式调用。
(1). 使用super()调用
- 语法:
super().__init__(参数) - 特点: 不需要显式提供父类名称,自动遵循 MRO(方法解析顺序),是多重继承下的最佳实践。
(2). 使用父类名显式调用
- 语法:
父类名.__init__(self, 参数) - 特点: 必须手动传入
self实例。
示例代码:
class Student(Human):
def __init__(self, name, secret, school):
# 方式 1:使用 super() (推荐)
super().__init__(name, secret)
# 方式 2:使用父类名调用
# Human.__init__(self, name, secret)
self.school = school # 初始化子类特有属性
4. isinstance - 类型检查
作用: 判断一个对象是否属于某个类或其子类。
5. 动态多维扩展 (*args)
作用: 利用可变长参数接收任意数量的参数。
class PointND:
def __init__(self, *args):
self.__coords = list(args) # 将坐标封装为私有列表
更多推荐


所有评论(0)