当前位置:首页>python>从零开始学python-类与对象_3

从零开始学python-类与对象_3

  • 2026-09-16 21:28:02
从零开始学python-类与对象_3

Hi~新朋友,记得点上面蓝字(网虫root)关注哟~

前言:

   Python是一门面向对象的编程语言,它支持使用类(class)和对象(object)来组织代码。通过类和对象,可以将数据(属性)和操作(方法)封装在一起,使代码更加模块化、易于维护和复用。

9. 方法

方法是定义在类内部的函数,用于描述对象的行为。根据作用域和绑定方式的不同,Python中有三种常见的方法:实例方法、类方法和静态方法。

9.1 实例方法

  • 实例方法的第一个参数必须是 self,它绑定到调用该方法的实例,操作实例变量。通过实例调用时,Python会自动将实例作为 self 传入。实例方法可以访问实例变量和类变量(通过 self.__class__ 或类名)。

  • 调用方式:只能通过实例调用(obj.method())。

  • 关键区别:依赖对象状态(通过 self 访问实例变量)。

示例1:

class Dog:    def __init__(self, name):        self.name = name    def bark(self):        print(f"{self.name} 汪汪叫!")dog = Dog("旺财")dog.bark()   # 输出:旺财 汪汪叫!

示例2:实例方法与实例变量的交互

class BankAccount:    def __init__(self, owner, balance=0):        self.owner = owner    # 实例变量        self.balance = balance  # 实例变量    # 实例方法:操作实例变量    def deposit(self, amount):        self.balance += amount        return f"{self.owner} deposited ${amount}. New balance: ${self.balance}"# 创建对象account1 = BankAccount("Alice", 100)account2 = BankAccount("Bob", 50)# 调用实例方法print(account1.deposit(50))  # 输出: Alice deposited $50. New balance: $150print(account2.deposit(100)) # 输出: Bob deposited $100. New balance: $150# 实例方法无法通过类名直接调用(会报错)# BankAccount.deposit(100)  # 错误!缺少self参数

✅验证:

  • deposit 方法通过 self.balance 修改实例状态。

  • account1.deposit(50) 仅影响 account1,不影响 account2。

9.2 类方法

  • 类方法使用 @classmethod 装饰器定义,第一个参数是 cls,代表类本身。

  • 类方法既可以由类调用,也可以由实例调用(Class.method() 或 obj.method()),但 cls 始终指向类。

  • 类方法可以访问类变量,但不能直接访问实例变量(因为没有实例)。

  • 关键区别:操作类变量,不依赖实例状态(通过cls访问类属性)。

示例1:

class Dog:    species = "Canis familiaris"    @classmethod    def get_species(cls):        return cls.speciesprint(Dog.get_species())   # 通过类调用:Canis familiarisdog = Dog()print(dog.get_species())   # 通过实例调用:Canis familiaris

类方法常用于创建工厂方法(返回类的实例)或访问/修改类属性。

示例2:类方法与类变量的交互

class Car:    total_cars = 0  # 类变量    def __init__(self, model):        self.model = model        Car.total_cars += 1  # 通过类名修改类变量    # 类方法:重置类变量    @classmethod    def reset_total(cls):        cls.total_cars = 0# 创建对象car1 = Car("Toyota Camry")car2 = Car("Honda Civic")# 验证类变量print(Car.total_cars)  # 输出: 2 (初始总数)# 调用类方法(通过类名)Car.reset_total()print(Car.total_cars)  # 输出: 0 (重置成功)# 通过实例调用类方法(同样有效)car1.reset_total()print(Car.total_cars)  # 输出: 0

✅ 验证:

  • total_cars 是类变量,通过 Car.total_cars 访问。

  • reset_total 是类方法,修改 cls.total_cars(cls 指向 Car 类)。

  • 通过 car1.reset_total() 调用,cls 仍指向 Car 类。

实例方法 vs 类方法:关键区别总结

特性
实例方法 (Instance Methods)
类方法 (Class Methods)
第一个参数
self
(表示对象本身)
cls
(表示类本身)
操作对象
操作实例变量(依赖对象状态)
操作类变量(依赖类状态)
调用方式
仅通过实例调用(obj.method())
通过类名或实例调用(Class.method() 或 obj.method())
典型用途
对象行为(如 deposit(), greet())
类级操作(如工厂方法、重置类状态)
示例
def withdraw(self, amount):@classmethod def create_car(cls, model):

错误常见点:在类方法中忘记 @classmethod 装饰器。

9.3 静态方法

静态方法使用 @staticmethod 装饰器定义,它既不需要 self 也不需要 cls 参数,可以看作是一个在类命名空间下的普通函数。静态方法不访问实例或类的属性(除非显式通过类名),通常用于实现一些与类相关但独立于具体实例的逻辑。

class MathUtil:    @staticmethod    def add(x, y):        return x + yprint(MathUtil.add(3, 5))   # 输出:8

9.4 实例方法、类方法与静态方法的区别

为了更清晰地选择使用哪种方法,下面从定义、访问能力和典型用途等方面进行对比。

特性
实例方法
类方法
静态方法
第一个参数
self(实例自身)
cls(类自身)
无特殊参数
可访问实例变量
是
否
否
可访问类变量
是(通过self.__class__或类名)
是(通过cls)
否(需显式通过类名)
调用方式
只能通过实例调用
可通过类或实例调用
可通过类或实例调用
自动传入的参数
实例对象
类对象
无
典型用途
操作实例数据(依赖对象状态)
操作类数据、工厂方法
工具函数、逻辑验证(不依赖类和实例状态)

详细示例1:

class Student:    school = "第一中学"  # 类变量    def __init__(self, name, grade):        self.name = name      # 实例变量        self.grade = grade    def display_info(self):        # 实例方法,可访问实例变量和类变量        print(f"姓名:{self.name},年级:{self.grade},学校:{self.school}")    @classmethod    def change_school(cls, new_school):        # 类方法,修改类变量        cls.school = new_school    @classmethod    def from_string(cls, info_str):        # 类方法作为工厂方法,创建实例        name, grade = info_str.split(',')        return cls(name, int(grade))    @staticmethod    def is_valid_grade(grade):        # 静态方法,验证年级是否有效        return 1 <= grade <= 12# 使用实例方法s1 = Student("小明", 5)s1.display_info()  # 姓名:小明,年级:5,学校:第一中学# 使用类方法修改类变量Student.change_school("第二中学")s2 = Student("小红", 3)s2.display_info()  # 姓名:小红,年级:3,学校:第二中学# 使用类方法创建对象s3 = Student.from_string("小刚,8")s3.display_info()  # 姓名:小刚,年级:8,学校:第二中学# 使用静态方法print(Student.is_valid_grade(10))  # Trueprint(Student.is_valid_grade(15))  # False

详细示例2:综合应用实例变量、类变量、实例方法、类方法

class Library:    # 类变量:所有图书馆共享的馆藏数量    total_books = 0    def __init__(self, name):        self.name = name  # 实例变量        self.books = []   # 实例变量(独立于其他图书馆)        Library.total_books += 1  # 更新类变量    # 实例方法:添加书籍(操作实例变量)    def add_book(self, book):        self.books.append(book)        return f"Added '{book}' to {self.name} library."    # 类方法:获取所有图书馆总数(操作类变量)    @classmethod    def get_total_libraries(cls):        return f"Total libraries: {cls.total_books}"    # 类方法:创建新图书馆(工厂方法)    @classmethod    def create_public_library(cls, name):        return cls(name)  # 调用__init__创建新实例# 创建图书馆public_lib = Library("City Public Library")university_lib = Library("University Library")# 验证实例变量print(public_lib.name)  # 输出: City Public Libraryprint(university_lib.books)  # 输出: [] (独立实例变量)# 验证类变量print(Library.total_books)  # 输出: 2 (类变量更新)print(public_lib.get_total_libraries())  # 输出: Total libraries: 2 (类方法)# 使用类方法创建新图书馆new_lib = Library.create_public_library("County Library")print(new_lib.name)  # 输出: County Libraryprint(Library.total_books)  # 输出: 3 (类变量更新)

✅ 验证:

  • total_books 类变量被正确更新(3个图书馆)。

  • public_lib.books 和 university_lib.books 是独立的列表。

  • create_public_library 作为类方法成功创建新实例。

10. 特殊方法(魔术方法)

Python中的特殊方法(也称为魔术方法)是以双下划线开头和结尾的方法,用于实现类的内置操作。通过重写这些方法,可以自定义对象的行为。

10.1 常用特殊方法

  • __init__(self, ...):构造函数,在对象创建时调用。

  • __str__(self):定义当使用 str() 或 print() 时返回的字符串。

  • __repr__(self):定义对象的“官方”字符串表示,通常用于调试,应尽可能还原对象创建方式。

  • __del__(self):析构函数,在对象被垃圾回收前调用。

  • __call__(self, ...):使对象可以像函数一样被调用。

  • __len__(self):定义 len() 函数的行为。

  • __getitem__(self, key):定义通过 obj[key] 访问元素的行为。

  • __setitem__(self, key, value):定义通过 obj[key] = value 赋值的行为。

  • __eq__(self, other):定义相等比较 ==。

  • __lt__(self, other):定义小于比较 <,等等。

10.2 示例

class Book:    def __init__(self, title, author, pages):        self.title = title        self.author = author        self.pages = pages    def __str__(self):        return f"《{self.title}》 by {self.author}"    def __repr__(self):        return f"Book('{self.title}', '{self.author}', {self.pages})"    def __len__(self):        return self.pages    def __call__(self):        print(f"开始阅读《{self.title}》...")book = Book("Python编程", "张三", 300)print(str(book))      # 《Python编程》 by 张三print(repr(book))     # Book('Python编程', '张三', 300)print(len(book))      # 300book()                # 开始阅读《Python编程》...

通过实现特殊方法,我们可以让自定义类的对象表现得像内置类型一样自然。

11. 总结

概念
语法
作用
独立性
调用方式
实例变量
self.attribute = value
存储对象特定状态
每个对象独立
通过实例访问(obj.attr)
类变量
attribute = value
存储类级别共享数据
所有实例共享
通过类或实例访问(Class.attr 或 obj.attr)
实例方法
def method(self, ...):
操作实例变量(需 self)
依赖实例
通过实例调用(obj.method())
类方法
@classmethod
操作类变量或创建新实例
依赖 cls
通过类或实例调用(Class.method() 或 obj.method())

12. 常见错误预防

1.实例变量 vs 类变量混淆

❌ 错误:class Student: school = "Harvard"(类变量)但 self.school = "Harvard"(实例变量)

✅ 正确:

类变量:school = "Harvard"(在类体中)

实例变量:self.school = school(在 __init__ 中)

2.实例方法误用类方法

❌ 错误:def reset(self):(应为类方法)

✅ 正确:

@classmethoddef reset(cls):    cls.total_books = 0

3.类方法中使用 self

❌ 错误:def method(cls, self):(参数错误)

✅ 正确:def method(cls, ...):(第一个参数必须是 cls)

4.类变量修改导致意外行为

❌ 错误:class Config: MAX_SIZE = 100,然后 config.MAX_SIZE = 200(修改类变量)

✅ 正确:

需修改实例变量:config.MAX_SIZE = 200(创建实例变量,不影响其他实例)

需修改类变量:Config.MAX_SIZE = 200(影响所有实例)

【微语】不同的人生,有不同的幸福。去发现你所拥有幸运,少抱怨上苍的不公,把握属于自己的幸福。

网虫root

期待你的

分享

点赞

在看

最新文章

随机文章