跳到主要内容

Python vs JavaScript OOP 对比详解

1. Python 的 __xxx__ 方法(魔法方法/Dunder 方法)

Python 有大量的特殊方法,都是 双下划线开头和结尾

常见的魔法方法

class MyClass:
# 对象生命周期
def __init__(self): # 初始化
pass
def __new__(cls): # 创建实例(比 __init__ 更早)
pass
def __del__(self): # 析构函数
pass

# 字符串表示
def __str__(self): # print(obj)
pass
def __repr__(self): # repr(obj),开发者表示
pass

# 比较运算符
def __eq__(self, other): # obj1 == obj2
pass
def __lt__(self, other): # obj1 < obj2
pass
def __le__(self, other): # obj1 <= obj2
pass
def __gt__(self, other): # obj1 > obj2
pass
def __ge__(self, other): # obj1 >= obj2
pass
def __ne__(self, other): # obj1 != obj2
pass

# 算术运算符
def __add__(self, other): # obj1 + obj2
pass
def __sub__(self, other): # obj1 - obj2
pass
def __mul__(self, other): # obj1 * obj2
pass
def __truediv__(self, other): # obj1 / obj2
pass

# 容器操作
def __len__(self): # len(obj)
pass
def __getitem__(self, key): # obj[key]
pass
def __setitem__(self, key, value): # obj[key] = value
pass
def __contains__(self, item): # item in obj
pass
def __iter__(self): # for x in obj
pass

# 属性访问
def __getattr__(self, name): # obj.attr(找不到时调用)
pass
def __setattr__(self, name, value): # obj.attr = value
pass
def __delattr__(self, name): # del obj.attr
pass

# 可调用
def __call__(self): # obj()
pass

# 上下文管理器
def __enter__(self): # with obj:
pass
def __exit__(self, *args): # with 结束时
pass

为什么有这么多?

因为 Python 希望你能自定义一切行为!

class Vector:
def __init__(self, x, y):
self.x = x
self.y = y

def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)

def __mul__(self, scalar):
return Vector(self.x * scalar, self.y * scalar)

def __str__(self):
return f"Vector({self.x}, {self.y})"

def __len__(self):
return int((self.x**2 + self.y**2)**0.5)

def __eq__(self, other):
return self.x == other.x and self.y == other.y

v1 = Vector(1, 2)
v2 = Vector(3, 4)

print(v1 + v2) # Vector(4, 6) ← 调用 __add__
print(v1 * 3) # Vector(3, 6) ← 调用 __mul__
print(len(v1)) # 2 ← 调用 __len__
print(v1 == v2) # False ← 调用 __eq__

2. Python:类为主还是函数为主?

答案:Python 是多范式语言,既支持类也支持函数!

Python 支持多种编程范式

# 1. 面向对象(OOP)
class Dog:
def __init__(self, name):
self.name = name

def bark(self):
print(f"{self.name}在叫")

# 2. 函数式编程
def double(x):
return x * 2

numbers = [1, 2, 3, 4]
result = list(map(double, numbers)) # [2, 4, 6, 8]

# 3. 过程式编程
x = 10
y = 20
z = x + y
print(z)

Python 的实际情况

# Python 标准库大量使用函数
import math
print(math.sqrt(16)) # 函数

import json
data = json.loads('{"a": 1}') # 函数

# 但也有很多类
from datetime import datetime
now = datetime.now() # 类

from pathlib import Path
p = Path("test.txt") # 类

# 甚至混用
import os
os.listdir(".") # 函数
path = os.path.join("a", "b") # 函数

# 但在类中
class MyClass:
pass

实际项目中的使用

# 数据科学:函数为主
import numpy as np
import pandas as pd

arr = np.array([1, 2, 3]) # 函数创建
df = pd.read_csv("data.csv") # 函数
result = df.mean() # 方法

# Web 框架:类和函数混用
from flask import Flask
app = Flask(__name__) # 类

@app.route('/') # 装饰器
def index(): # 函数
return "Hello"

# Django:类为主
from django.views import View
class MyView(View): # 类
def get(self, request):
return response

# PyTorch:类为主
import torch.nn as nn
class MyModel(nn.Module): # 类
def __init__(self):
super().__init__()

def forward(self, x):
return x

结论:Python 没有明显的"类为主"或"函数为主",看场景!


3. JavaScript vs Python:OOP 对比

JavaScript:函数是一等公民

// JS 中,类本质就是函数
class Dog {
constructor(name) {
this.name = name;
}
}

console.log(typeof Dog); // "function" ← 类就是函数!

// 等价的函数写法
function DogFunc(name) {
this.name = name;
}

// 都能用 new
const dog1 = new Dog("旺财");
const dog2 = new DogFunc("小黑");

Python:类是类,函数是函数

# Python 中,类和函数是不同的东西
class Dog:
def __init__(self, name):
self.name = name

def some_function():
pass

print(type(Dog)) # <class 'type'> ← 类是 type 的实例
print(type(some_function)) # <class 'function'> ← 函数是 function

# 不能这样用
# dog = Dog.call(None, "旺财") ❌ 不像 JS 的 apply/call

4. Python 是"真的"面向对象吗?

答案:Python 比 JavaScript 更加"纯粹"的面向对象!

Python:一切皆对象

# 数字是对象
x = 42
print(type(x)) # <class 'int'>
print(dir(x)) # [..., '__add__', '__mul__', ...]
print(x.__add__(8)) # 50(调用方法)

# 字符串是对象
s = "hello"
print(type(s)) # <class 'str'>
print(s.upper()) # HELLO

# 函数也是对象!
def my_func():
pass

print(type(my_func)) # <class 'function'>
my_func.custom_attr = "属性" # 可以给函数加属性!
print(my_func.custom_attr)

# 类也是对象!
class Dog:
pass

print(type(Dog)) # <class 'type'>
Dog.custom = "类属性"
print(Dog.custom)

# 模块也是对象!
import math
print(type(math)) # <class 'module'>

JavaScript:不是所有东西都是对象

// 基本类型不是对象
const x = 42;
console.log(typeof x); // "number"(不是对象)

// 但可以临时包装成对象
console.log(x.toString()); // "42"

// 函数是对象
function func() {}
console.log(typeof func); // "function"
func.prop = "属性";
console.log(func.prop); // "属性"

// null 不是对象(虽然 typeof 说是)
console.log(typeof null); // "object"(这是 bug)

Python 的 OOP 特点

1. 一切都是对象

# 连 None 都是对象
print(type(None)) # <class 'NoneType'>

# True/False 是对象
print(type(True)) # <class 'bool'>
print(True.__class__) # <class 'bool'>

# 甚至类型本身也是对象
print(type(int)) # <class 'type'>
print(type(type)) # <class 'type'>(type 是自己的实例!)

2. 显式的 self

# Python 强制你写 self
class Dog:
def bark(self): # ← 必须写 self
print(self.name)

# JavaScript 隐式的 this
class Dog {
bark() { // ← 不需要写 this 作为参数
console.log(this.name);
}
}

3. 多重继承

# Python 原生支持多重继承
class A:
def method_a(self):
print("A")

class B:
def method_b(self):
print("B")

class C(A, B): # 继承多个类
pass

c = C()
c.method_a() # A
c.method_b() # B

# JavaScript 不支持多重继承
// class C extends A, B {} ❌ 语法错误

4. 元类(Metaclass)

# Python 有元类系统(超级高级)
class Meta(type):
def __new__(cls, name, bases, attrs):
print(f"创建类:{name}")
return super().__new__(cls, name, bases, attrs)

class MyClass(metaclass=Meta): # 使用元类
pass
# 输出:创建类:MyClass

# JavaScript 没有元类的概念

对比总结

特性PythonJavaScript
一切皆对象✅ 真的一切⚠️ 基本类型除外
类的本质类是 type 的实例类是函数
OOP 纯粹度非常纯粹基于原型,不够纯粹
多重继承✅ 支持❌ 不支持
元编程强大(元类、描述符)有限(Proxy)
编程范式多范式(OOP、函数式、过程式)多范式(但以函数为核心)
魔法方法大量 __xxx__少量 Symbol

Python OOP 的强大之处

1. 运算符重载

class Money:
def __init__(self, amount):
self.amount = amount

def __add__(self, other):
return Money(self.amount + other.amount)

def __str__(self):
return f"${self.amount}"

m1 = Money(100)
m2 = Money(50)
print(m1 + m2) # $150 ← 非常自然!

JavaScript 不能这样做:

class Money {
constructor(amount) {
this.amount = amount;
}
}

const m1 = new Money(100);
const m2 = new Money(50);
// m1 + m2 ← ❌ 不能重载 + 运算符

2. 描述符(Descriptor)

class Descriptor:
def __get__(self, obj, type=None):
return "获取属性"

def __set__(self, obj, value):
print(f"设置属性:{value}")

class MyClass:
attr = Descriptor()

obj = MyClass()
print(obj.attr) # 获取属性
obj.attr = "新值" # 设置属性:新值

3. 上下文管理器

class File:
def __init__(self, filename):
self.filename = filename

def __enter__(self):
self.file = open(self.filename)
return self.file

def __exit__(self, *args):
self.file.close()

# 使用
with File("test.txt") as f:
content = f.read()
# 自动关闭文件

最终答案

Python 是真的面向对象吗?

✅ 是的!而且比 JavaScript 更纯粹!

理由:

  1. 一切皆对象 - 包括数字、函数、类、模块
  2. 类是一等公民 - 不是函数的语法糖
  3. 丰富的魔法方法 - 自定义一切行为
  4. 强大的元编程 - 元类、描述符等高级特性
  5. 多重继承 - 完整的 OOP 支持

Python 类为主还是函数为主?

答案:都支持,看场景!

  • 数据科学、脚本 → 函数为主
  • 框架、大型项目 → 类为主
  • 实际项目 → 混用

JavaScript vs Python OOP

# JavaScript:函数式 + 原型继承
# - 类是函数的语法糖
# - 原型链
# - 灵活但不够纯粹

# Python:纯粹的 OOP + 多范式
# - 类是真正的类
# - 一切皆对象
# - 严谨且功能强大

总结:Python 的 OOP 比 JS 更"正统",更接近传统的面向对象语言(如 Java、C++)!