Python中class对象/属性/方法/继承/多态/魔法方法详解
myzbx 2025-08-06 22:01 62 浏览
一、基础入门:认识类和对象
1. 类和对象的概念
在 Python 中,类(class)是一种抽象的概念,用于定义对象的属性和行为,而对象(也称为实例)则是类的具体表现。比如,“汽车” 可以是一个类,它有颜色、品牌、速度等属性,也有启动、加速、刹车等行为;而一辆具体的 “红色特斯拉Model3” 就是 “汽车” 类的一个对象。
2. 类的基本结构
class Car:
def __init__(self, color, brand):
self.color = color
self.brand = brand
def start(self):
print(f"{self.brand} {self.color}汽车启动了!")
def accelerate(self):
print("汽车加速中...")
- __init__ 方法是构造函数,用于在创建对象时初始化对象的属性,self代表对象本身。
- start 和 accelerate 是类的方法,用于定义对象的行为。
3. 创建类和对象
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(f"{self.name}汪汪叫!")
# 创建Dog类的对象
my_dog = Dog("小白", 3)
my_dog.bark()
my_dog = Dog("小黑", 4)
my_dog.bark()关键要点:
- 调用类名并传入参数(如果有),即可创建对象,如 Dog("小白", 3)。
- 通过对象名调用方法,如 my_dog.bark()。
二、属性与方法:深入了解对象特征
1. 属性和方法的分类
类的属性和方法是对象的核心组成部分,属性分为类属性和实例属性,方法分为实例方法、类方法和静态方法。我们先从实例属性和实例方法开始深入了解。
2. 实例属性和实例方法
实例属性会因为类对象的不同而不同。
class Person:
def __init__(self, name, gender):
self.name = name
self.gender = gender
def introduce(self):
print(f"我叫{self.name},性别{self.gender}。")
person1 = Person("Alice", "女")
person1.introduce()
person1.age = 25 # 动态添加属性
print(f"{person1.name}的年龄是{person1.age}岁。")
#输出为:
我叫Alice,性别女。
Alice的年龄是25岁。
person1 = Person("Jams", "男")
person1.introduce()
person1.age = 29 # 动态添加属性
print(f"{person1.name}的年龄是{person1.age}岁。")
#输出为
我叫Jams,性别男。
Jams的年龄是29岁。
操作说明:
- 实例属性可以在 __init__ 方法中初始化,也可以在创建对象后动态添加。
- 实例属性可通过self.属性来访问。
- 实例方法是类中定义的普通的函数,函数中可以使用实例属性。
3. 类属性
类属性是属于类本身的属性,它被类的所有实例共享。
class Company:
company_name = "ABC 公司" # 类属性
def __init__(self, employee_name):
self.employee_name = employee_name # 实例属性
emp1 = Company("张三")
emp2 = Company("李四")
print(Company.company_name) # 通过类名访问类属性
print(emp1.company_name) # 通过实例访问类属性
print(emp1.employee_name) # 访问实例属性
#输出为:
ABC 公司
ABC 公司
张三
Company.company_name = "XYZ 公司" # 修改类属性
print(emp2.company_name) # 所有实例的类属性都被修改
#输出为:
XYZ 公司
emp2.company_name = "YYY 公司" # 通过实例修改类属性
print(emp2.company_name)
print(emp1.company_name)
print(Company.company_name)
#输出为: 类属性其实没有被修改
YYY 公司
XYZ 公司
XYZ 公司注意事项:
- 类属性可以通过类名或实例名访问,但通过实例名修改类属性时,实际上是为该实例创建了一个同名的实例属性,不会影响类属性本身 。
- 类属性常用于定义一些全局的、共享的数据,如配置信息等。
三、类方法和静态方法:特殊的方法类型
1. 类方法
类方法是与类相关联的方法,它不需要实例化对象即可调用,并且只能访问类属性,不能访问实例属性。在定义类方法时,需要使用 @classmethod 装饰器,第一个参数通常为 cls,代表类本身。
class MathUtils:
pi = 3.1415926
@classmethod
def circle_area(cls, radius):
return cls.pi * radius ** 2
area = MathUtils.circle_area(5)
print(f"半径为 5 的圆面积:{area}")
应用场景:
- 当方法的操作只涉及类属性,不依赖于实例的状态时,适合定义为类方法 。
- 类方法还常用于创建对象的替代构造函数,例如从不同的数据格式中创建对象。
2. 静态方法
静态方法是一种不依赖于类和实例的方法,它不需要传递 self 或 cls 参数,相当于定义在类中的普通函数。使用@staticmethod装饰器来定义静态方法。
class StringUtils:
@staticmethod
def reverse_string(s):
return s[::-1]
result = StringUtils.reverse_string("Hello, World!")
print(f"反转后的字符串:{result}")
使用特点:
- 静态方法不能访问类属性和实例属性,也不能调用类方法和实例方法,它仅仅是将函数逻辑与类进行了逻辑上的分组 。
- 当某个功能与类有一定关联,但又不需要访问类或实例的状态时,可定义为静态方法,提高代码的组织性。
四、继承与多态:提升代码复用性和灵活性
1. 继承
继承允许一个类(子类)继承另一个类(父类)的属性和方法,提高代码复用性。
class Animal:
def __init__(self, species):
self.species = species
def speak(self):
print("动物发出声音")
class Cat(Animal):
def speak(self):
print("猫咪喵喵叫")
my_cat = Cat("猫")
my_cat.speak()
重点说明:
- 子类通过在括号内指定父类名来继承,如 class Cat(Animal)。
- 子类可以重写父类的方法,实现特定的行为。
2. 多态
多态指的是不同的类对象对同一方法有不同的实现。
class Circle:
def area(self):
return 3.14 * self.radius ** 2
class Rectangle:
def area(self):
return self.width * self.height
circle = Circle()
circle.radius = 5
print(f"圆形面积:{circle.area()}")
rectangle = Rectangle()
rectangle.width = 4
rectangle.height = 6
print(f"矩形面积:{rectangle.area()}")
函数功能介绍:
- 虽然 Circle 和 Rectangle 类的 area 方法实现不同,但都可以通过统一的方式调用。
五、魔法方法:赋予对象特殊能力
Python 中有许多以 __ 开头和结尾的魔法方法,用于实现特殊功能。
1. 构造和析构方法
- __init__(self, ...):前面已经介绍过,它是构造函数,用于在创建对象时初始化对象的属性。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
- __del__(self):析构函数,当对象被销毁时调用。不过由于Python有垃圾回收机制,此方法的使用场景相对较少。
class Resource:
def __init__(self):
print("资源已创建")
def __del__(self):
print("资源已释放")
res = Resource()
del res
2. 比较方法
- __eq__(self, other):定义对象相等的比较规则,对应 == 运算符。
class Student:
def __init__(self, id):
self.id = id
def __eq__(self, other):
return self.id == other.id
s1 = Student(1)
s2 = Student(1)
print(s1 == s2) - __ne__(self, other):定义对象不相等的比较规则,对应 !=运算符。通常如果实现了 __eq__,Python 会自动处理 __ne__,但也可以手动实现。
- __lt__(self, other)、__le__(self, other)、__gt__(self, other)、__ge__(self, other):分别对应 <、<=、>、>= 运算符,用于定义对象之间的大小比较规则。
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def __lt__(self, other):
return self.area() < other.area()
r1 = Rectangle(2, 3)
r2 = Rectangle(4, 5)
print(r1 < r2)
3. 算术运算方法
- __add__(self, other):定义对象相加的行为,对应 + 运算符。前面已有示例。
- __sub__(self, other):定义对象相减的行为,对应 - 运算符。
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
v1 = Vector(3, 4)
v2 = Vector(1, 2)
v3 = v1 - v2
print(v3.x, v3.y)
- __mul__(self, other)、__truediv__(self, other)、__floordiv__(self, other) 等:分别对应 *、/、// 等运算符。
4. 容器相关方法
- __len__(self):定义对象的长度,对应 len() 函数。
class MyList:
def __init__(self, items):
self.items = items
def __len__(self):
return len(self.items)
my_list = MyList([1, 2, 3, 4])
print(len(my_list))
- __getitem__(self, key):定义通过索引或键访问对象元素的行为,对应 obj[key] 操作。
class MyList:
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return self.items[index]
my_list = MyList([1, 2, 3, 4])
print(my_list[2])
- __setitem__(self, key, value):定义通过索引或键设置对象元素的行为,对应 obj[key] = value 操作。
- __delitem__(self, key):定义通过索引或键删除对象元素的行为,对应 del obj[key] 操作。
5. 字符串表示方法
- __str__(self):返回对象的字符串表示,用于 print() 函数和 str() 函数。前面已有示例。
- __repr__(self):返回对象的 “官方” 字符串表示,通常用于调试和开发环境。如果未实现 __str__,print() 也会调用 __repr__。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Point({self.x}, {self.y})"
p = Point(1, 2)
print(repr(p))
六、实用案例展示
案例 1:学生管理系统
class Student:
school_name = "阳光中学" # 类属性
def __init__(self, name, id_number, grade):
self.name = name
self.id_number = id_number
self.grade = grade
def show_info(self):
print(f"姓名:{self.name},学号:{self.id_number},年级:{self.grade},学校:{self.school_name}")
students = [
Student("张三", "2023001", "一年级"),
Student("李四", "2023002", "二年级")
]
for student in students:
student.show_info()
案例 2:图形绘制模拟
class Shape:
shape_count = 0 # 类属性
def __init__(self):
Shape.shape_count += 1
def draw(self):
print("绘制图形")
@classmethod
def get_shape_count(cls):
return cls.shape_count
@staticmethod
def shape_type():
return "通用图形"
class Triangle(Shape):
def draw(self):
print("绘制三角形")
class Square(Shape):
def draw(self):
print("绘制正方形")
shapes = [
Triangle(),
Square()
]
for shape in shapes:
shape.draw()
print(f"图形总数:{Shape.get_shape_count()}")
print(f"图形类型:{Shape.shape_type()}")
七、闭坑指南
属性访问错误
- 错误操作:在方法中未通过self访问对象属性,或者访问不存在的属性;混淆类属性和实例属性的访问与修改方式。
- 解决方法:在类的方法中,始终使用 self 来访问属性;在使用属性前,确保其已被正确初始化或动态添加;修改类属性时,通过类名进行操作,避免通过实例名意外创建同名实例属性 。
继承理解错误
- 错误操作:子类继承父类后,未正确调用父类方法,或者重写方法时逻辑错误。
- 解决方法:如果子类需要保留父类方法的部分功能,可以使用super() 调用父类方法;重写方法时,仔细检查逻辑是否符合需求。
魔法方法误用
- 错误操作:随意定义魔法方法,导致与 Python 内置逻辑冲突;未按照魔法方法的规范实现功能。
- 解决方法:在使用魔法方法前,充分了解其用途和参数要求;遵循 Python 的约定,避免自定义不符合规范的魔法方法。
对象生命周期混淆
- 错误操作:在对象已被销毁后,尝试访问其属性或调用方法;不理解对象的创建和销毁时机。
- 解决方法:明确对象的作用域,避免在不合适的地方使用已失效的对象;必要时,可以手动释放资源(虽然 Python 有垃圾回收机制)。
类方法、静态方法使用混淆
- 错误操作:将需要访问实例属性的方法定义为类方法或静态方法;在静态方法中试图访问类属性或实例属性。
- 解决方法:根据方法的功能和对属性的依赖情况,准确选择使用实例方法、类方法或静态方法 。如果方法只涉及类属性,可定义为类方法;若方法与类和实例的状态均无关,则定义为静态方法。
八、总结回顾
本章我们学习并掌握了从基础的类和对象创建,到属性、方法的深入运用,再到继承、多态和魔法方法的高级特性,在后续实践中我们要避开常见的 “坑点”,多实践不同案例,在Python编程的世界里搭建出属于自己的精彩程序。
九、class 对象常用函数与方法汇总
函数 / 方法 | 功能 | 示例 |
__init__(self, ...) | 构造函数,初始化对象属性 | def __init__(self, name, age): self.name = name; self.age = age |
self.属性名 | 访问对象属性 | print(self.name) |
对象名.方法名() | 调用对象方法 | my_dog.bark() |
super().__init__(...) | 在子类中调用父类构造函数 | super().__init__(species) |
__add__(self, other) | 定义对象相加行为 | def __add__(self, other): return Point(self.x + other.x, self.y + other.y) |
__str__(self) | 返回对象的字符串表示 | def __str__(self): return f"({self.x}, {self.y})" |
类名.类属性 | 访问类属性 | print(Company.company_name) |
@classmethod 装饰的方法 | 定义类方法,可访问类属性 | @classmethod<br>def circle_area(cls, radius):<br> return cls.pi * radius ** 2 |
@staticmethod 装饰的方法 | 定义静态方法,独立于类和实例 | @staticmethod<br>def reverse_string(s):<br> return s[::-1] |
__del__(self) | 析构函数,对象销毁时调用 | def __del__(self): print("对象已销毁") |
__eq__(self, other) | 定义对象相等比较规则 | def __eq__(self, other): return self.id == other.id |
__lt__(self, other) | 定义对象小于比较规则 | def __lt__(self, other): return self.area() < other.area() |
__len__(self) | 定义对象长度 | def __len__(self): return len(self.items) |
__getitem__(self, key) | 定义通过索引或键访问元素行为 | def __getitem__(self, index): return self.items[index] |
__repr__(self) | 返回对象官方字符串表示 | def __repr__(self): return f"Point({self.x}, {self.y})" |
相关推荐
- 如何设计一个优秀的电子商务产品详情页
-
加入人人都是产品经理【起点学院】产品经理实战训练营,BAT产品总监手把手带你学产品电子商务网站的产品详情页面无疑是设计师和开发人员关注的最重要的网页之一。产品详情页面是客户作出“加入购物车”决定的页面...
- 怎么在JS中使用Ajax进行异步请求?
-
大家好,今天我来分享一项JavaScript的实战技巧,即如何在JS中使用Ajax进行异步请求,让你的网页速度瞬间提升。Ajax是一种在不刷新整个网页的情况下与服务器进行数据交互的技术,可以实现异步加...
- 中小企业如何组建,管理团队_中小企业应当如何开展组织结构设计变革
-
前言写了太多关于产品的东西觉得应该换换口味.从码农到架构师,从前端到平面再到UI、UE,最后走向了产品这条不归路,其实以前一直再给你们讲.产品经理跟项目经理区别没有特别大,两个岗位之间有很...
- 前端监控 SDK 开发分享_前端监控系统 开源
-
一、前言随着前端的发展和被重视,慢慢的行业内对于前端监控系统的重视程度也在增加。这里不对为什么需要监控再做解释。那我们先直接说说需求。对于中小型公司来说,可以直接使用三方的监控,比如自己搭建一套免费的...
- Ajax 会被 fetch 取代吗?Axios 怎么办?
-
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天给大家带来的主题是ajax、fetch...
- 前端面试题《AJAX》_前端面试ajax考点汇总
-
1.什么是ajax?ajax作用是什么?AJAX=异步JavaScript和XML。AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX可以使网页实...
- Ajax 详细介绍_ajax
-
1、ajax是什么?asynchronousjavascriptandxml:异步的javascript和xml。ajax是用来改善用户体验的一种技术,其本质是利用浏览器内置的一个特殊的...
- 6款可替代dreamweaver的工具_替代powerdesigner的工具
-
dreamweaver对一个web前端工作者来说,再熟悉不过了,像我07年接触web前端开发就是用的dreamweaver,一直用到现在,身边的朋友有跟我推荐过各种更好用的可替代dreamweaver...
- 我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊
-
接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝...
- 福斯《死侍》发布新剧照 "小贱贱"韦德被改造前造型曝光
-
时光网讯福斯出品的科幻片《死侍》今天发布新剧照,其中一张是较为罕见的死侍在被改造之前的剧照,其余两张剧照都是死侍在执行任务中的状态。据外媒推测,片方此时发布剧照,预计是为了给不久之后影片发布首款正式预...
- 2021年超详细的java学习路线总结—纯干货分享
-
本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象...
- 不用海淘,真黑五来到你身边:亚马逊15件热卖爆款推荐!
-
Fujifilm富士instaxMini8小黄人拍立得相机(黄色/蓝色)扫二维码进入购物页面黑五是入手一个轻巧可爱的拍立得相机的好时机,此款是mini8的小黄人特别版,除了颜色涂装成小黄人...
- 2025 年 Python 爬虫四大前沿技术:从异步到 AI
-
作为互联网大厂的后端Python爬虫开发,你是否也曾遇到过这些痛点:面对海量目标URL,单线程爬虫爬取一周还没完成任务;动态渲染的SPA页面,requests库返回的全是空白代码;好不容易...
- 最贱超级英雄《死侍》来了!_死侍超燃
-
死侍Deadpool(2016)导演:蒂姆·米勒编剧:略特·里斯/保罗·沃尼克主演:瑞恩·雷诺兹/莫蕾娜·巴卡林/吉娜·卡拉诺/艾德·斯克林/T·J·米勒类型:动作/...
- 停止javascript的ajax请求,取消axios请求,取消reactfetch请求
-
一、Ajax原生里可以通过XMLHttpRequest对象上的abort方法来中断ajax。注意abort方法不能阻止向服务器发送请求,只能停止当前ajax请求。停止javascript的ajax请求...
- 一周热门
- 最近发表
- 标签列表
-
- HTML 简介 (30)
- HTML 响应式设计 (31)
- HTML URL 编码 (32)
- HTML Web 服务器 (31)
- HTML 表单属性 (32)
- HTML 音频 (31)
- HTML5 支持 (33)
- HTML API (36)
- HTML 总结 (32)
- HTML 全局属性 (32)
- HTML 事件 (31)
- HTML 画布 (32)
- HTTP 方法 (30)
- 键盘快捷键 (30)
- CSS 语法 (35)
- CSS 轮廓宽度 (31)
- CSS 谷歌字体 (33)
- CSS 链接 (31)
- CSS 定位 (31)
- CSS 图片库 (32)
- CSS 图像精灵 (31)
- SVG 文本 (32)
- 时钟启动 (33)
- HTML 游戏 (34)
- JS Loop For (32)
