学 Python 的人,大多数都会在某个阶段被"类"卡住。刚接触的时候,很多人都会觉得:"这东西好抽象啊,像不像传说中的编程黑魔法?"😵
别慌,其实类没那么神秘。你可以把它想成生活里常见的"模具"或者"样板"。就像裁缝做衣服,先得有个样板,才能照着样板去裁布、缝衣服。类就是那个样板,而衣服就是你根据样板做出来的"对象"。
今天,我们就把 Python 的类从头到尾聊一遍,不整花里胡哨的玄学,把它拆开、讲透,让你读完之后能说一句:"哦,原来就这回事啊!"
一、类与对象:从生活例子讲起
假设你家里有一只猫,叫 Mimi,今年 2 岁。你想在代码里把它记录下来,该怎么办?
先来点最直接的:
python
class Cat:
def __init__(self, name, age):
self.name = name # 属性:姓名
self.age = age # 属性:年龄
# 基于类创建对象
my_cat = Cat("Mimi", 2)
print(my_cat.name) # 输出:Mimi
print(my_cat.age) # 输出:2
看到没?
Cat
就是模具。Mimi
这只猫,就是通过模具造出来的对象。
记住一句话就够了:类是样板,对象是成品。
二、最简单的类:空壳也能跑起来
Python 里,创建类的关键字是 class
。习惯上,类名用首字母大写的驼峰命名法 ,比如 Person
,而不是 person
。
来个最简单的例子:
python
class Person:
pass # 一个什么也不做的空类
person1 = Person()
print(person1) # 输出:<__main__.Person object at 0x00000......>
这里的 pass
就是个占位符。代码写上它,表示"这里我先空着,后面再补"。
这类写法在项目里很常见,通常是为了先搭好架子,后续再补充逻辑。
三、构造函数:让对象一出生就有属性
有了类之后,你肯定希望对象一创建就带着一些数据。比如狗的名字、品种,这就需要构造函数 ------ __init__
。
python
class Dog:
def __init__(self, name, breed):
self.name = name # 属性:宠物名
self.breed = breed # 属性:品种
my_dog = Dog("Buddy", "Golden Retriever")
print(my_dog.name) # 输出:Buddy
print(my_dog.breed) # 输出:Golden Retriever
__init__
在对象创建的时候会自动执行,不需要你手动调用。就像孩子出生的时候,你不用额外说"给他个名字",医生会直接在出生证明上写好。
注意一点:构造函数里不能用 return
返回值,否则 Python 会直接报错。
四、self:类里的"身份证"
很多新手被 self
搞得晕头转向。其实它就是个引用,指向"当前这个对象"。
举个例子:
python
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(f"{self.name} says Woof!")
def birthday(self):
self.age += 1
print(f"Happy Birthday, {self.name}! Now you are {self.age} years old.")
my_dog = Dog("Buddy", 3)
my_dog.bark() # 输出:Buddy says Woof!
my_dog.birthday() # 输出:Happy Birthday, Buddy! Now you are 4 years old.
当你写 my_dog.bark()
时,Python 会自动把 my_dog
传给方法里的 self
。所以 self.name
就是 my_dog.name
。
简单说:self
就是对象的身份证,证明"这是我"。
五、属性和方法:对象能"带东西"和"做事情"
在类里:
- 属性 = 数据,比如人的名字、年龄。
- 方法 = 动作,比如"跑"、"叫"。
ruby
class Circle:
def __init__(self, radius):
self.radius = radius # 属性:半径
def area(self):
return 3.14 * self.radius ** 2 # 方法:返回面积
my_circle = Circle(5)
print(my_circle.area()) # 输出:78.5
是不是很像现实生活?你有身高体重这些"属性",还能跑跳吃饭这些"方法"。
六、类属性:全家共享的"姓氏"
有时候,某些属性不是某个实例独有的,而是整个类都通用的。比如,所有狗都属于"犬科"。这就叫类属性。
ini
class Dog:
species = "犬科" # 类属性
def __init__(self, name):
self.name = name # 实例属性
dog1 = Dog("Buddy")
dog2 = Dog("Max")
print(dog1.species) # 输出:犬科
print(dog2.species) # 输出:犬科
Dog.species = "猫科"
print(dog1.species) # 输出:猫科
print(dog2.species) # 输出:猫科
小技巧:类属性推荐用类名来访问,比如 Dog.species
,这样更清晰。
七、三种方法:实例、类、静态
Python 的方法分三类,用途不一样:
-
实例方法(最常用):操作对象的数据。
rubyclass Cat: def __init__(self, name): self.name = name def greet(self): return f"Meow! I am {self.name}." cat = Cat("Mimi") print(cat.greet()) # 输出:Meow! I am Mimi.
-
类方法 :操作类的数据,用
@classmethod
声明。pythonclass Dog: species = "犬科" @classmethod def change_species(cls, new_species): cls.species = new_species Dog.change_species("猫科") print(Dog.species) # 输出:猫科
-
静态方法 :和类、对象无关的独立函数,用
@staticmethod
声明。pythonclass Math: @staticmethod def add(a, b): return a + b print(Math.add(3, 5)) # 输出:8
记住一句口诀:实例方法管自己,类方法管全家,静态方法管外面的世界。
八、特殊方法:让对象更"Pythonic"
Python 有一堆以双下划线开头结尾的方法,帮你定制类的行为。
str 和 repr
python
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person(name={self.name}, age={self.age})"
def __repr__(self):
return f"<Person {self.name} ({self.age} years old)>"
p = Person("Alice", 30)
print(str(p)) # 输出:Person(name=Alice, age=30)
print(repr(p)) # 输出:<Person Alice (30 years old)>
一个是给用户看的(__str__
),一个是给开发者看的(__repr__
)。
eq
ruby
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
return self.x == other.x and self.y == other.y
p1 = Point(1, 2)
p2 = Point(1, 2)
print(p1 == p2) # 输出:True
九、继承与多态:写一次,复用到底
写类最强大的地方在于继承。子类可以继承父类的方法,还能改写它。
ruby
class Animal:
def speak(self):
raise NotImplementedError("子类必须实现此方法。")
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
animals = [Dog(), Cat()]
for animal in animals:
print(animal.speak())
继承让代码复用;多态让"同一个接口,不同实现"成为可能。
十、写在最后:学会类,才算入门 Python
类这东西,看上去绕,但真理解了,你会发现它其实就是把现实世界搬进代码。
- 你有属性(名字、年龄);
- 你有方法(吃饭、睡觉、学习);
- 你也有继承(来自父母的基因😄)。
学会类,你就能写出更清晰、更好扩展的代码。这也是新手到进阶的关键一步。
别怕它难,多敲几个例子,你会发现: 类不是门槛,而是帮你走得更远的工具。