类和对象的基本概念及属性和方法的常见分类和使用场景
在程序设计中,“面向对象编程(OOP)”是最核心的一种思想。Python 是一种典型的面向对象语言,理解“类”、“对象”、“属性”、“方法”的概念,是成为中高级 Python 开发者的第一步。
面向对象编程(Object-Oriented Programming,简称OOP)是一种通过组织对象来设计程序的编程方法。
Python天生就是面向对象的模块化编程。
一、类和对象的基本概念
示意图:
/-------> BYD E6(京A.88888) 实例,对象
车(类)
\-------> BMW X5(京B.00000) 实例(对象)
/-------> 小京巴(户籍号:000001)
狗(类)
\-------> 导盲犬(户籍号:000002)
/-------> 100 (对象)
int(类)
\-------> 200 (对象)
1 、类→Class
1. 类的概念
类是对一类对象的抽象,是对象的模板或蓝图。它定义了对象的属性(特征)和方法(功能)。
类是现实世界事物的抽象模型,是创建对象的“模板”或“蓝图”。
你可以把类想象成建筑图纸——它不会自己“存在”,但你可以用它来建造很多“房子”,这些房子就是对象。
2.类的创建
- 数据成员:表明事物的特征。 相当于变量
- 方法成员:表明事物的功能。 相当于函数
- 通过
class
关键字定义类。
2、对象→Object
人以群分,每个人就是一个对象。
对象是根据类创建的 具体实例。每个对象都有类中定义的属性和方法,并可以有各自独立的数据。
举个例子:
类是“狗”这个概念,具体的“哈士奇”、“金毛”就是对象。
3、创建类和对象的基本语法
class Dog:
def __init__(self, name, breed):
self.name = name # 实例属性
self.breed = breed
def bark(self): # 实例方法
print(f"{self.name} is barking!")
# 创建对象
dog1 = Dog("Buddy", "Labrador")
dog1.bark() # 输出:Buddy is barking!
----------------------------------------------------
class Dog:
pass
# 创建第一个实例:
dog1 = Dog()
print(id(dog1)) # 打印这个对象的ID
# 创建第二个实例对象
dog2 = Dog() # dog2 绑定一个Dog类型的对象
print(id(dog2))
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
print(f"My name is {self.name} and I am {self.age} years old.")
person1 = Person("Alice", 25)
person2 = Person("Bob", 30)
二、属性与方法
1、实例属性
属于每个对象自身的数据。
定义在 __init__()
方法中,使用 self.xxx
。
属性的使用语法:
实例.属性名
-
属性使用
class Dog: def eat(self, food): print(self.color, '的', self.kinds, '正在吃', food) # 创建一个实例: dog1 = Dog() dog1.kinds = "京巴" # 添加属性 dog1.color = "白色" dog1.color = "黄色" # 修改属性 print(dog1.color, '的', dog1.kinds) dog2 = Dog() dog2.kinds = "藏獒" dog2.color = "棕色" print(dog2.color, '的', dog2.kinds)
-
实例方法和实例属性(实例变量)结合在一起用
class Dog: def eat(self, food): print(self.color, '的', self.kinds, '正在吃', food) # 创建第一个对象 dog1 = Dog() dog1.kinds = '京巴' # 添加属性kinds dog1.color = '白色' # 添加属性color dog1.eat("骨头") dog2 = Dog() dog2.kinds = '牧羊犬' dog2.color = '灰色' dog2.eat('包子')
2、实例方法
- 最常见的方法。
- 第一个参数必须是
self
,代表对象本身。 - 操作对象的实例属性。
class Circle:
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius * self.radius
--------------------------------------------------------------
class 类名(继承列表):
def 实例方法名(self, 参数1, 参数2, ...):
"文档字符串"
语句块
-
实例方法就是函数,至少有一个指向实例对象的形参self
-
调用
实例.实例方法名(调用传参) # 或 类名.实例方法名(实例, 调用传参)
-
带有实例方法的简单的Dog类
class Dog: """这是一个种小动物的定义 这种动物是狗(犬)类,用于创建各种各样的小狗 """ def eat(self, food): """此方法用来描述小狗吃东西的行为""" print("小狗正在吃", food) def sleep(self, hour): print("小狗睡了", hour, "小时!") def play(self, obj): print("小狗正在玩", obj) dog1 = Dog() dog1.eat("骨头") dog1.sleep(1) dog1.play('球') help(Dog) # 可以看到Dog类的文档信息
3、类属性
- 类属性是类的属性,此属性属于类,不属于此类的实例
- 作用:
- 通常用来存储该类创建的对象的共有属性
- 类属性说明
- 类属性,可以通过该类直接访问
- 类属性,可以通过类的实例直接访问
class Student:
school = "Springfield High" # 类属性
def __init__(self, name):
self.name = name
4、类方法
-
第一个参数是
cls
,表示类本身。 -
使用
@classmethod
装饰器定义。 -
常用于创建对象的备用构造方法或操作类属性。
-
类方法是用于描述类的行为的方法,类方法属于类,不属于该类创建的对象
-
说明
- 类方法需要使用@classmethod装饰器定义
- 类方法至少有一个形参用于绑定类,约定为 clsclscls
- 类和该类的实例都可以调用类方法
- 类方法不能访问此类创建的对象的实例属性
class Person
count = 0
def __init__(self)
# 示例1
class A:
v = 0
@classmethod
def set_v(cls, value):
cls.v = value
@classmethod
def get_v(cls):
return cls.v
print(A.get_v())
A.set_v(100)
print(A.get_v())
a = A()
print(a.get_v())
#示例2
class MyClass:
class_attr = 0 # 类属性
def __init__(self, value):
self.instance_attr = value # 实例属性
@classmethod
def modify_class_attr(cls, new_value):
cls.class_attr = new_value
print(f"类属性已修改为: {cls.class_attr}")
@classmethod
def try_modify_instance_attr(cls):
try:
cls.instance_attr = 10 # 事出反常必有妖
except AttributeError as e:
print(f"错误: {e}")
# 创建类的实例
obj = MyClass(5)
# 调用类方法修改类属性
MyClass.modify_class_attr(20) # 输出: 类属性已修改为: 20
MyClass.try_modify_instance_attr() # 事出反常必有妖
5、静态方法(Static Methods)
-
不需要
self
或cls
。 -
使用
@staticmethod
装饰器定义。 -
像普通函数一样,但放在类中组织更清晰。
class Math:
@staticmethod
def add(x, y):
return x + y
🔸 使用场景:方法逻辑独立于类和实例,只是为了代码组织在类中。
让代码更有组织性
避免污染全局命名空间
class A:
class_attr = 42 # 类属性
def __init__(self, value):
self.instance_attr = value # 实例属性
@staticmethod
def myadd(a, b):
# 只能访问传递的参数,不能访问实例属性
return a + b
# 创建类实例
a = A(10)
# 调用静态方法
print(A.myadd(100, 200)) # 输出: 300
print(a.myadd(300, 400)) # 输出: 700
6、使用场景举例总结
分类 | 定义位置 | 用法 | 常见用途 |
---|---|---|---|
实例属性 | __init__() 中 | self.xxx | 每个对象的数据 |
类属性 | 类体中 | 类名.xxx 或 对象.xxx | 所有对象共享数据 |
实例方法 | 类中定义 | 有 self 参数 | 操作当前对象 |
类方法 | 类中定义 | 有 cls 参数 | 操作类的状态 |
静态方法 | 类中定义 | 无 self 或 cls | 与对象和类无关的逻辑 |
7、构造方法
构造方法**__new__()
**:
- 负责对象的 创建 和内存分配的。
- 在对象实例化时被调用,负责返回一个新的对象实例。
- 通常不需要显式地定义
__new__()
方法,Python会调用基类 objectobjectobject 的__new__()
方法。
class MyClass:
def __new__(cls, *args, **kwargs):
print("调用 __new__ 方法,创建对象")
return super().__new__(cls)
def __init__(self, value):
print("调用 __init__ 方法,初始化对象")
self.value = value
# 创建对象
obj = MyClass(10)
8、 初始化方法
-
一旦对象被创建,Python会调用
__init__()
来初始化对象的属性。 -
语法格式:
class 类名(继承列表): def __init__(self[, 形参列表]): 语句块 # [] 代表其中的内容可省略
接收实参到
__init__
方法中 -
代码示例:
class MyClass: def __new__(cls, *args, **kwargs): print("调用 __new__ 方法,创建对象") return super().__new__(cls) def __init__(self, value): print("调用 __init__ 方法,初始化对象") self.value = value # 创建对象 obj = MyClass(10)
-
输出:
调用 __new__ 方法,创建对象 调用 __init__ 方法,初始化对象
9、魔术方法
魔术方法是一种特殊的方法,用双下划线包裹,例如__init__
,__str__
,__add__
等。这些方法允许您自定义类的行为,以便与内置Python功能(如+运算符、迭代、字符串表示等)交互。
用于 定义类的行为,如:
- 如何初始化对象
- 如何让对象支持运算符(如
+
,==
) - 如何定义对象的打印方式
- 如何实现容器行为(索引、切片)
常用方法:
- init(self, …)`: 初始化对象,通常用于设置对象的属性。
__str__(self)
: 定义对象的字符串表示形式,可通过str(object)
或print(object)
调用。例如,您可以返回一个字符串,描述对象的属性。__repr__(self)
: 定义对象的“官方”字符串表示形式,通常用于调试。可通过repr(object)
调用。__len__(self)
: 定义对象的长度,可通过len(object)
调用。通常在自定义容器类中使用。__getitem__(self, key)
: 定义对象的索引操作,使对象可被像列表或字典一样索引。例如,object[key]
。__setitem__(self, key, value)
: 定义对象的赋值操作,使对象可像列表或字典一样赋值。例如,object[key] = value
。__delitem__(self, key)
: 定义对象的删除操作,使对象可像列表或字典一样删除元素。例如,del object[key]
。__iter__(self)
: 定义迭代器,使对象可迭代,可用于for
循环。__next__(self)
: 定义迭代器的下一个元素,通常与__iter__
一起使用。__add__(self, other)
: 定义对象相加的行为,使对象可以使用+
运算符相加。例如,object1 + object2
。__sub__(self, other)
: 定义对象相减的行为,使对象可以使用-
运算符相减。__eq__(self, other)
: 定义对象相等性的行为,使对象可以使用==
运算符比较。__lt__(self, other)
: 定义对象小于其他对象的行为,使对象可以使用<
运算符比较。__gt__(self, other)
: 定义对象大于其他对象的行为,使对象可以使用>
运算符比较。__call__(self, other)
是一个特殊的方法(也称为“魔法方法”),它允许一个对象像函数一样被调用。
1. 构造与销毁类行为
魔术方法 | 作用 |
---|---|
__init__(self, ...) | 构造方法,创建对象时自动调用 |
__del__(self) | 析构方法,对象销毁时调用(不推荐依赖) |
python复制编辑class Person:
def __init__(self, name):
self.name = name
print("Person created.")
def __del__(self):
print("Person destroyed.")
2. 字符串表示
魔术方法 | 作用 |
---|---|
__str__(self) | 用于 print() 、str() ,返回用户可读字符串 |
__repr__(self) | 用于 repr() 或交互式解释器,返回开发者调试字符串 |
python复制编辑class Book:
def __init__(self, title):
self.title = title
def __str__(self):
return f"《{self.title}》"
def __repr__(self):
return f"Book('{self.title}')"
3. 运算符重载(操作符)
运算符 | 魔术方法 |
---|---|
+ | __add__ |
- | __sub__ |
* | __mul__ |
/ | __truediv__ |
== | __eq__ |
< | __lt__ |
<= | __le__ |
python复制编辑class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def __str__(self):
return f"({self.x}, {self.y})"
p1 = Point(1, 2)
p2 = Point(3, 4)
print(p1 + p2) # 输出:(4, 6)
4. 容器相关
魔术方法 | 作用 |
---|---|
__len__ | 用于 len(obj) |
__getitem__ | 支持索引访问,如 obj[i] |
__setitem__ | 支持索引赋值,如 obj[i] = x |
__contains__ | 用于 in 操作 |
__iter__ , __next__ | 支持迭代器 |
python复制编辑class MyList:
def __init__(self, data):
self.data = data
def __getitem__(self, index):
return self.data[index]
def __len__(self):
return len(self.data)
ml = MyList([10, 20, 30])
print(len(ml)) # 3
print(ml[1]) # 20
5. 上下文管理器(with)
魔术方法 | 作用 |
---|---|
__enter__ | with 语句进入时自动调用 |
__exit__ | with 语句块结束时自动调用 |
python复制编辑class FileMock:
def __enter__(self):
print("打开资源")
return self
def __exit__(self, exc_type, exc_value, traceback):
print("关闭资源")
with FileMock():
print("处理中...")
输出:
复制编辑打开资源
处理中...
关闭资源
总结:魔术方法分类总览
类别 | 方法 | 作用 |
---|---|---|
构造 | __init__ , __new__ | 初始化对象 |
析构 | __del__ | 对象销毁时调用 |
表示 | __str__ , __repr__ | 对象的字符串描述 |
运算 | __add__ , __eq__ , __lt__ , … | 运算符重载 |
容器 | __len__ , __getitem__ , __setitem__ , __contains__ | 支持容器行为 |
上下文 | __enter__ , __exit__ | 实现 with 管理资源 |
迭代器 | __iter__ , __next__ | 使对象可迭代 |
调用 | __call__ | 让对象像函数一样调用 |
布尔值 | __bool__ | 转换为 True/False |