在 Python 中,函数(Function) 和 方法(Method) 在定义语法上几乎一样(都用 def),但它们的归属关系和调用方式有本质区别

1. 核心区别一句话总结

函数 (Function):定义在模块(文件)级别,不属于任何类。它是独立的。
方法 (Method):定义在类(Class)内部,属于某个类或实例。它必须通过对象或类来调用。

2. 代码对比

A. 函数 (Function)
定义在类外面,直接属于 .py 文件(模块)

# 这是一个函数
def say_hello(name):
    return f"Hello, {name}!"

# 直接调用,不需要对象
result = say_hello("Alice") 
print(result) # 输出: Hello, Alice!

B. 方法 (Method)

class User:
    def __init__(self, name):
        self.name = name

    # 1. 实例方法 (Instance Method) - 最常见
    # 第一个参数必须是 self (代表实例对象本身)
    def greet(self):
        return f"Hello, I am {self.name}"

    # 2. 类方法 (Class Method)
    # 第一个参数必须是 cls (代表类本身),用 @classmethod 装饰
    @classmethod
    def create_guest(cls):
        return cls("Guest")

    # 3. 静态方法 (Static Method)
    # 不需要 self 或 cls,用 @staticmethod 装饰,行为最像普通函数
    @staticmethod
    def validate_name(name):
        return len(name) > 0

# --- 调用方式的区别 ---

u = User("Bob")

# 调用实例方法:必须通过 对象.方法()
# Python 会自动把 u 传给 self
print(u.greet()) 

# 调用类方法:可以通过 类.方法() 或 对象.方法()
print(User.create_guest()) 

# 调用静态方法:可以通过 类.方法() 或 对象.方法()
# 它就是个挂在类命名空间下的普通函数
print(User.validate_name("Bob")) 

3. 深度解析:为什么要有 self?

这是 Java 开发者最容易困惑的地方
在 Java 中:

public class User {
    String name;
    public String greet() { // 隐含了 this
        return "Hello, " + this.name;
    }
}

Java 编译器隐式地传递了 this 指针。
在 Python 中:

def greet(self): # 必须显式写出 self
    return "Hello, " + self.name

Python 是显式优于隐式。当你调用 u.greet() 时,Python 解释器实际上在执行 User.greet(u)。

如果你定义时忘了写 self,调用时会报错:TypeError: greet() takes 0 positional arguments but 1 was given(因为解释器强行塞入了一个对象实例,但你没接住)。

特殊情况:绑定与非绑定

在 Python 中,方法其实是绑定了对象的函数

class MyClass:
    def func(self):
        return "I am a method"

obj = MyClass()

# 1. 通过对象调用 (绑定方法)
# 此时 func 已经绑定了 obj,self 自动就是 obj
print(obj.func()) 

# 2. 通过类调用 (非绑定方法 / 函数)
# 此时它只是一个普通的函数,必须手动传入实例
print(MyClass.func(obj)) 
# 上面这两行代码的效果是完全一样的!

4. 给 Java 开发者的对照表

特性 Java Python 备注
定义位置 必须在 Class 内 可在模块内 (函数) 或 Class 内 (方法) Python 更灵活
第一个参数 隐含 this 显式 self (实例) 或 cls (类) Python 必须手写
静态成员 static 关键字 @staticmethod 装饰器 行为类似
类成员 static + 类名访问 @classmethod Python 区分更细
调用方式 obj.method() obj.method()Class.method(obj) 本质相同
独立功能 需创建工具类 Utils 直接写函数 def util() Python 不需要为了放函数而造类

5. 什么时候用函数,什么时候用方法?

  • 用函数:
    逻辑不依赖任何特定的对象状态(不需要 self)。
    通用的工具逻辑(如:数学计算、字符串处理、数据格式转换)。
    脚本入口 (main)。

  • 用方法:
    逻辑需要访问或修改对象的属性 (self.name, self.count)。
    逻辑属于某个特定概念的行为(如 user.login(), order.pay())。
    需要多态支持(子类重写父类方法)。

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐