【Python】函数、方法与魔术方法

245 阅读4分钟

🟡函数与方法

函数与方法的区别主要体现在是否与类或实例绑定

函数是独立的代码块,通过 def 关键字定义,接收参数并返回结果,不依赖任何对象状态

def add(a, b):     ##调用 `add(2, 3)` 时,函数只根据输入参数执行计算,行为完全独立。
    return a + b

方法是定义在类内部的函数,是绑定到对象的状态操作,第一个参数(selfcls)表示它与某个对象相关

class Book:
    def __init__(self, title):
        self.title = title
    def get_title(self):
        return self.title

book = Book("Python 101")
print(book.get_title())  # 输出:Python 101

🟡方法类别

在面向对象编程中,方法根据其绑定对象和职责分为以下几类:实例方法、类方法、静态方法和魔术方法。

🔘实例方法:操作个体状态

实例方法与类的具体实例绑定,第一个参数是 self,表示调用该方法的实例。它的核心职责是操作实例的属性。例如,在书店系统中,每本书有独一无二的属性(如书名、作者、ISBN、库存量)。减少某本书库存的行为显然与具体实例相关:

class Book:
    def __init__(self, title, author, isbn, stock):
        self.title = title
        self.author = author
        self.isbn = isbn
        self.stock = stock

    def decrease_stock(self, amount):      # 这就是实例方法
        if amount > self.stock:            # 通过 `self` 访问和修改 `stock` 属性
            raise ValueError("库存不足")
        self.stock -= amount               # 通过 `self` 访问和修改 `stock` 属性

🔘 类方法:管理共享状态

类方法通过 @classmethod 装饰器定义,第一个参数是 cls,表示类本身。操作类级别的共享状态,或作为工厂方法创建特定类型的实例。例如,书店需要跟踪所有书籍的总库存:

class Book:
    total_inventory = 0  # 类属性,记录总库存

    def __init__(self, title, author, isbn, stock):
        self.title = title
        self.author = author
        self.isbn = isbn
        self.stock = stock
        Book.total_inventory += stock

    @classmethod
    def get_total_inventory(cls):
        return cls.total_inventory

🔘 静态方法:独立逻辑的归属

静态方法通过 @staticmethod 装饰器定义,不绑定实例或类,行为上与普通函数相同。它的存在仅仅为了组织代码好看.....,将与类相关但不依赖对象状态的逻辑放在类中。例如,计算书籍折扣价:

class Book:
    @staticmethod
    def calculate_discount(price, discount_rate):  # 该方法不需要访问实例或类属性,提供的是通用逻辑
        return price * (1 - discount_rate)

🔘 魔术方法:定义对象行为

魔术方法是 Python 的特殊方法,由双下划线包围(如 __init____str__),由解释器在特定场景下自动调用。它们的核心职责是定义对象在特定上下文中的行为。例如:

  • __init__:初始化实例状态。在书店系统中,__init__ 确保每本书在创建时具备必要的属性
  • __str__:定义对象的字符串表示。
  • __eq__:定义对象比较逻辑。
class Book:
    def __init__(self, title, author, isbn, stock):
        self.title = title
        self.author = author
        self.isbn = isbn
        self.stock = stock

    def __str__(self):
        return f"{self.title} by {self.author}"

调用 print(Book("Python 101", "John Doe", "123456", 10)) 会输出 Python 101 by John Doe

🔘 工厂函数:动态创建对象

书店系统需要支持不同类型的书籍(如纸质书和电子书),每种书籍的创建方式不同。工厂函数(通常作为静态方法或独立函数)根据参数动态创建不同类型的对象:

class PhysicalBook(Book):
    def __init__(self, title, author, isbn, stock, weight):
        super().__init__(title, author, isbn, stock)
        self.weight = weight

class EBook(Book):
    def __init__(self, title, author, isbn, stock, format):
        super().__init__(title, author, isbn, stock)
        self.format = format

class BookFactory:
    @staticmethod
    def create_book(book_type, title, author, isbn, stock, **kwargs):
        if book_type == "physical":
            return PhysicalBook(title, author, isbn, stock, kwargs.get("weight"))
        elif book_type == "ebook":
            return EBook(title, author, isbn, stock, kwargs.get("format"))
        raise ValueError("Unknown book type")

BookFactory.create_book 是一个静态方法,根据 book_type 参数选择合适的构造函数,创建 PhysicalBookEBook 实例。这种设计增强了系统的灵活性,调用者无需关心具体的类,只需提供参数即可。

🟡 函数与方法的调用模式

Python 的调用模式通常基于点操作,因为 Python 是一门彻底的面向对象语言。模块、类和实例都是对象,点操作提供了明确的命名空间和上下文。例如:

  • 模块函数:math.sqrt(16) 调用模块对象 mathsqrt 属性。
  • 实例方法:book.decrease_stock(2) 调用实例 book 的方法,自动传递 self
  • 类方法:Book.get_total_inventory() 调用类的共享状态。
  • 静态方法:Book.calculate_discount(100, 0.1) 调用类中的独立逻辑。

点操作的核心优势是模块化可读性。例如,book.decrease_stock(2) 清楚地表明操作针对 book 实例,而独立函数 decrease_stock(book, 2) 则不够直观。