类和对象
类(class):相当于一张蓝图或模板
对象(object):根据蓝图造出来的具体实物
类:
定义:class(#关键字#) 类名称:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class BlogPost: def __init__(self, title, date, content=""): self.title = title self.date = date self.content = content self.is_published = False
def publish(self): self.is_published = True print(f"✅ 文章《{self.title}》已发布!")
def show_info(self): print(f"📄 标题:{self.title}") print(f"📅 日期:{self.date}") print(f"📌 状态:{'已发布' if self.is_published else '草稿'}")
|
对象(实例化):
定义:对象名称 = 类名称(属性1,属性2….)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| post1 = BlogPost("Python基础温习", "2026-07-11", "今天学习了 Git 重命名...")
post2 = BlogPost("Hexo部署心得", "2026-07-10")
post1.show_info()
post1.publish()
post2.show_info()
|
类的核心三大特性:
1.封装:把数据和操作数据的方法打包在一起,藏在内部细节。只需调用,无需关心内部如何修改。
2.继承:子类可以继承父类的遗产。
1 2 3 4 5 6 7 8 9 10
| class DiaryPost(BlogPost): def __init__(self, title, date, mood): super().__init__(title, date) self.mood = mood
def show_mood(self): print(f"今天心情:{self.mood}")
diary = DiaryPost("今日复盘", "2026-07-11", "😊 开心") diary.publish()
|
3.多态:不同类可以有同名的方法。子类可以重写(覆盖)自己的方法,程序会自动调用正确的那个。
self:它是实例自身的引用。
__init__:不是构造方法,它是“初始化方法”,对象已经创建好内存后才调用它来赋值。
类名建议大写
属性定义
1,单下划线开头_(“保护”属性/约定俗成)
写法:
含义:这是一个约定内部使用的属性,请不要在类外部直接访问
本质:Python解释器不会做任何修改,外部依然可以强行访问到它。
1 2 3 4 5 6 7
| class BlogPost: def __init__(self, title): self._title = title self._draft = True
post = BlogPost("Python基础") print(post._title)
|
建议:如果你只是不想让外部随便改,用_就够了,它主要起提醒作用。
2.双下划线开头——(真正的”私有”/名称修饰)
写法:
含义:Python会强制把属性名称改成(下划线)类名(下划线)属性名,这叫名称修饰,目的防止子类意外覆盖父类的属性。
本质:外部无法直接通过原名访问,但如果知道修饰后的名字,依然能强行调用(所以也不算绝对安全,只是“防君子不防小人”)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class BlogPost: def __init__(self, title): self.__title = title self.__content = ""
def publish(self): print(f"发布:{self.__title}")
post = BlogPost("Python基础")
print(post._BlogPost__title)
|
3.双下划线开头和结尾(双下划线)XXX(双下划线)(魔法方法/特殊属性)
写法:
含义:这是Python内置的特殊方法或属性,不是私有属性。
建议:千万不要自定义这种名字的属性,这是Python内部保留的命名空间。
最佳结合@property控制访问权限:
在实际开发中,最标准的做法是:把属性定为“私有”(用开头(单下划线)或(双下划线)),然后通过@property装饰器提供自读访问,通过@属性名.setter提供可控修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class BlogPost: def __init__(self, title): self.__title = title
@property def title(self): return self.__title
@title.setter def title(self, new_title): if len(new_title) > 0: self.__title = new_title else: print("❌ 标题不能为空")
post = BlogPost("Git入门") print(post.title)
post.title = "Git进阶" print(post.title)
post.title = ""
|
对比表:
| 写法 |
外部访问情况 |
用途 |
推荐程度 |
self.name |
直接完全公开 |
普通公有属性 |
不涉及隐私时使用 |
self._name |
可以访问(但会被 IDE 警告) |
约定内部使用,子类可用 |
常用,大多数场景够用 |
self.__name |
无法直接访问(会报错) |
强制防止子类意外覆盖 |
防止继承冲突时使用 |
@property |
像属性一样调用,但经过方法处理 |
对私有属性做读取/写入拦截 |
最推荐,既安全又优雅 |
现代python语法糖:
@dataclass(数据类):不用写冗长的init和repr,自动帮你生成。
1 2 3 4 5 6 7 8 9 10
| from dataclasses import dataclass
@dataclass class BlogPost: title: str content: str = "" is_published: bool = False
p = BlogPost("Git入门") print(p)
|
slots(内存优化):默认每个对象有个dict字典存属性,费内存。用slots固定属性名,能省大量内存(适合创建成千上万个对象)。
1 2
| class BlogPost: __slots__ = ('title', 'content')
|