Skip to content

Python 核心语法和特性

从 JavaScript/TypeScript 开发者的视角学习 Python 基础

📖 学习目标

  • 掌握 Python 基础语法和数据类型
  • 理解 Python 与 JS/TS 的差异
  • 熟练使用 Python 的数据结构
  • 掌握函数定义和参数传递
  • 理解面向对象编程
  • 学会模块和包管理

预计学习时间:3-4 天
难度:⭐⭐

1. Python vs JavaScript 基础对比

1.1 变量和数据类型

JavaScript/TypeScript

typescript
// 变量声明
let name = "John";
const age = 30;
var isActive = true;

// 类型
let value: number = 42;
let message: string = "hello";
let flag: boolean = true;
let empty: null = null;
let notDefined: undefined = undefined;

Python

python
# 变量声明(无需关键字)
name = "John"
age = 30
is_active = True

# Python 类型(动态类型,但可使用类型提示)
value: int = 42
message: str = "hello"
flag: bool = True
empty = None  # Python 没有 undefined

# 注意:Python 使用 snake_case,而非 camelCase

关键差异

  • Python 没有 let/const/var,直接使用变量名
  • Python 使用 None 代替 nullundefined
  • Python 使用 True/False(首字母大写)
  • Python 推荐使用 snake_case 命名

1.2 基础数据类型详解

python
# 1. 数字类型
integer = 42                    # int
float_num = 3.14               # float
complex_num = 1 + 2j           # complex(复数)

# 数字运算
print(10 / 3)    # 3.333... (真除法)
print(10 // 3)   # 3 (整除)
print(10 % 3)    # 1 (取模)
print(2 ** 3)    # 8 (幂运算)

# 2. 字符串
single = 'Hello'
double = "World"
triple = '''多行
字符串'''

# 字符串操作(不可变)
text = "Python"
print(text[0])        # 'P' (索引)
print(text[-1])       # 'n' (负索引,从后往前)
print(text[0:3])      # 'Pyt' (切片)
print(text * 3)       # 'PythonPythonPython'
print("Py" in text)   # True (包含检查)

# f-string(类似 JS 的模板字符串)
name = "Alice"
age = 25
message = f"My name is {name} and I'm {age} years old"
print(message)  # My name is Alice and I'm 25 years old

# 3. 布尔类型
is_valid = True
is_empty = False

# 布尔运算(注意关键字不同)
result = True and False  # JS: &&
result = True or False   # JS: ||
result = not True        # JS: !

# 4. None(空值)
value = None
if value is None:  # 使用 is,而非 ==
    print("Value is None")

对比 JavaScript

javascript
// JS 中的真值和假值
Boolean(0)          // false
Boolean("")         // false
Boolean(null)       // false
Boolean(undefined)  // false
Boolean([])         // true ⚠️
Boolean({})         // true ⚠️
python
# Python 中的真值和假值
bool(0)          # False
bool("")         # False
bool(None)       # False
bool([])         # False ✅ 空列表为假
bool({})         # False ✅ 空字典为假
bool([1])        # True

2. 数据结构

2.1 列表(List)- 类似 JS 数组

python
# 创建列表
fruits = ["apple", "banana", "cherry"]
numbers = [1, 2, 3, 4, 5]
mixed = [1, "two", 3.0, True, None]  # 可以混合类型

# 访问元素
print(fruits[0])    # 'apple'
print(fruits[-1])   # 'cherry' (最后一个)

# 切片(强大的特性)
print(numbers[1:4])    # [2, 3, 4]
print(numbers[:3])     # [1, 2, 3] (前3个)
print(numbers[3:])     # [4, 5] (从索引3到末尾)
print(numbers[::2])    # [1, 3, 5] (步长为2)
print(numbers[::-1])   # [5, 4, 3, 2, 1] (反转)

# 列表操作
fruits.append("orange")         # 添加元素
fruits.insert(1, "grape")       # 在索引1插入
fruits.remove("banana")         # 删除指定元素
popped = fruits.pop()           # 删除并返回最后一个
fruits.extend(["kiwi", "mango"]) # 合并列表

# 列表推导式(强大的特性)
squares = [x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

evens = [x for x in range(20) if x % 2 == 0]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# 对比 JS
# JS: const squares = Array.from({length: 10}, (_, i) => i**2);
# JS: const evens = [...Array(20).keys()].filter(x => x % 2 === 0);

2.2 元组(Tuple)- 不可变列表

python
# 创建元组(不可变)
coordinates = (10, 20)
single_item = (42,)  # 注意:单元素元组需要逗号

# 元组解包
x, y = coordinates
print(x, y)  # 10 20

# 函数返回多个值(实际返回元组)
def get_user():
    return "Alice", 25, "alice@example.com"

name, age, email = get_user()

# 对比 JS
# JS 中需要使用数组或对象:
# const [name, age, email] = getUser();

2.3 字典(Dict)- 类似 JS 对象

python
# 创建字典
user = {
    "name": "Alice",
    "age": 25,
    "email": "alice@example.com"
}

# 访问元素
print(user["name"])           # 'Alice'
print(user.get("age"))        # 25
print(user.get("phone", "N/A"))  # 'N/A' (提供默认值)

# 修改和添加
user["age"] = 26
user["phone"] = "123-456-7890"

# 删除元素
del user["email"]
phone = user.pop("phone")  # 删除并返回值

# 遍历字典
for key in user:
    print(key, user[key])

for key, value in user.items():
    print(f"{key}: {value}")

# 字典推导式
squares = {x: x**2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# 对比 JS
"""
JS:
const user = {
  name: "Alice",
  age: 25,
  email: "alice@example.com"
};

// 访问
user.name
user["name"]

// 遍历
Object.keys(user)
Object.values(user)
Object.entries(user)
"""

2.4 集合(Set)- 唯一值集合

python
# 创建集合
numbers = {1, 2, 3, 4, 5}
unique = set([1, 2, 2, 3, 3, 3])  # {1, 2, 3}

# 集合运算
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

print(a | b)  # {1, 2, 3, 4, 5, 6} 并集
print(a & b)  # {3, 4} 交集
print(a - b)  # {1, 2} 差集
print(a ^ b)  # {1, 2, 5, 6} 对称差集

# 集合操作
numbers.add(6)
numbers.remove(1)
numbers.discard(99)  # 不存在也不报错

# 对比 JS
# JS: const numbers = new Set([1, 2, 3]);

3. 控制流

3.1 条件语句

python
# if-elif-else(注意没有 else if)
age = 18

if age < 13:
    print("Child")
elif age < 20:
    print("Teenager")
else:
    print("Adult")

# 三元运算符
status = "adult" if age >= 18 else "minor"

# 对比 JS
# JS: const status = age >= 18 ? "adult" : "minor";

# 条件表达式的真假判断
if []:  # 空列表为假
    print("Not empty")

if {}:  # 空字典为假
    print("Not empty")

if "":  # 空字符串为假
    print("Not empty")

if 0:   # 0 为假
    print("Not zero")

# 多条件判断
x = 5
if 1 < x < 10:  # Python 支持链式比较
    print("x is between 1 and 10")

# JS 需要写成: if (x > 1 && x < 10)

3.2 循环

python
# for 循环(遍历可迭代对象)
fruits = ["apple", "banana", "cherry"]

for fruit in fruits:
    print(fruit)

# 带索引的遍历
for index, fruit in enumerate(fruits):
    print(f"{index}: {fruit}")

# range 函数
for i in range(5):        # 0 到 4
    print(i)

for i in range(1, 6):     # 1 到 5
    print(i)

for i in range(0, 10, 2): # 0, 2, 4, 6, 8
    print(i)

# while 循环
count = 0
while count < 5:
    print(count)
    count += 1

# break 和 continue
for i in range(10):
    if i == 3:
        continue  # 跳过 3
    if i == 7:
        break     # 在 7 处停止
    print(i)

# else 子句(Python 特有)
for i in range(5):
    print(i)
else:
    print("Loop completed normally")  # 没有 break 时执行

# 对比 JS
"""
JS:
for (let i = 0; i < 5; i++) {
  console.log(i);
}

fruits.forEach((fruit, index) => {
  console.log(`${index}: ${fruit}`);
});
"""

4. 函数

4.1 函数定义

python
# 基本函数
def greet(name):
    """函数文档字符串(docstring)"""
    return f"Hello, {name}!"

result = greet("Alice")

# 多返回值
def get_stats(numbers):
    return min(numbers), max(numbers), sum(numbers)

min_val, max_val, total = get_stats([1, 2, 3, 4, 5])

# 默认参数
def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"

print(greet("Alice"))              # Hello, Alice!
print(greet("Bob", "Hi"))          # Hi, Bob!

# 关键字参数
def create_user(name, age, email=None):
    return {"name": name, "age": age, "email": email}

user = create_user(name="Alice", age=25)
user = create_user(age=30, name="Bob", email="bob@example.com")

# 对比 JS
"""
JS:
function greet(name, greeting = "Hello") {
  return `${greeting}, ${name}!`;
}

// JS 使用对象解构实现命名参数
function createUser({ name, age, email = null }) {
  return { name, age, email };
}
"""

4.2 可变参数

python
# *args - 可变位置参数(类似 JS 的 ...rest)
def sum_all(*numbers):
    """接受任意数量的参数"""
    return sum(numbers)

print(sum_all(1, 2, 3))        # 6
print(sum_all(1, 2, 3, 4, 5))  # 15

# **kwargs - 可变关键字参数
def print_info(**info):
    """接受任意数量的关键字参数"""
    for key, value in info.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=25, city="NYC")

# 组合使用
def complex_function(required, *args, optional="default", **kwargs):
    print(f"Required: {required}")
    print(f"Args: {args}")
    print(f"Optional: {optional}")
    print(f"Kwargs: {kwargs}")

complex_function(
    "value",
    1, 2, 3,
    optional="custom",
    extra1="a",
    extra2="b"
)

# 对比 JS
"""
JS:
function sumAll(...numbers) {
  return numbers.reduce((a, b) => a + b, 0);
}

function printInfo({ name, age, ...rest }) {
  console.log(name, age, rest);
}
"""

4.3 Lambda 函数

python
# lambda 表达式(匿名函数)
square = lambda x: x ** 2
print(square(5))  # 25

# 常用于高阶函数
numbers = [1, 2, 3, 4, 5]

# map
squared = list(map(lambda x: x**2, numbers))
# [1, 4, 9, 16, 25]

# filter
evens = list(filter(lambda x: x % 2 == 0, numbers))
# [2, 4]

# sorted
users = [
    {"name": "Alice", "age": 25},
    {"name": "Bob", "age": 30},
    {"name": "Charlie", "age": 20}
]
sorted_users = sorted(users, key=lambda u: u["age"])

# 对比 JS
"""
JS:
const square = x => x ** 2;

const squared = numbers.map(x => x ** 2);
const evens = numbers.filter(x => x % 2 === 0);
const sortedUsers = users.sort((a, b) => a.age - b.age);
"""

5. 面向对象编程

5.1 类的定义

python
class User:
    """用户类"""
    
    # 类变量(所有实例共享)
    species = "Human"
    count = 0
    
    # 构造函数
    def __init__(self, name, age):
        """初始化实例"""
        # 实例变量
        self.name = name
        self.age = age
        User.count += 1
    
    # 实例方法
    def greet(self):
        return f"Hello, I'm {self.name}"
    
    def have_birthday(self):
        self.age += 1
    
    # 类方法
    @classmethod
    def get_count(cls):
        return cls.count
    
    # 静态方法
    @staticmethod
    def is_adult(age):
        return age >= 18
    
    # 特殊方法(魔术方法)
    def __str__(self):
        """字符串表示"""
        return f"User({self.name}, {self.age})"
    
    def __repr__(self):
        """调试表示"""
        return f"User(name='{self.name}', age={self.age})"

# 使用类
user1 = User("Alice", 25)
user2 = User("Bob", 30)

print(user1.greet())         # Hello, I'm Alice
print(User.get_count())      # 2
print(User.is_adult(16))     # False
print(user1)                 # User(Alice, 25)

# 对比 JS
"""
JS:
class User {
  static count = 0;
  
  constructor(name, age) {
    this.name = name;
    this.age = age;
    User.count++;
  }
  
  greet() {
    return `Hello, I'm ${this.name}`;
  }
  
  static getCount() {
    return User.count;
  }
}
"""

5.2 继承

python
class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        raise NotImplementedError("Subclass must implement")

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)  # 调用父类构造函数
        self.breed = breed
    
    def speak(self):
        return f"{self.name} says Woof!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} says Meow!"

# 使用
dog = Dog("Buddy", "Golden Retriever")
cat = Cat("Whiskers")

print(dog.speak())  # Buddy says Woof!
print(cat.speak())  # Whiskers says Meow!

# 多重继承(Python 支持,JS 不支持)
class Flyable:
    def fly(self):
        return "Flying!"

class Bird(Animal, Flyable):
    def speak(self):
        return f"{self.name} says Chirp!"

bird = Bird("Tweety")
print(bird.speak())  # Tweety says Chirp!
print(bird.fly())    # Flying!

5.3 属性和封装

python
class BankAccount:
    def __init__(self, balance=0):
        self._balance = balance  # 约定:单下划线表示"受保护"
        self.__secret = "secret" # 双下划线表示"私有"
    
    # 使用 @property 创建计算属性
    @property
    def balance(self):
        """获取余额"""
        return self._balance
    
    @balance.setter
    def balance(self, value):
        """设置余额"""
        if value < 0:
            raise ValueError("Balance cannot be negative")
        self._balance = value
    
    def deposit(self, amount):
        if amount > 0:
            self._balance += amount
    
    def withdraw(self, amount):
        if 0 < amount <= self._balance:
            self._balance -= amount
            return True
        return False

# 使用
account = BankAccount(1000)
print(account.balance)  # 1000(调用 getter)
account.balance = 1500  # 调用 setter
account.deposit(500)

# 对比 JS
"""
JS:
class BankAccount {
  #balance = 0;  // 私有字段
  
  get balance() {
    return this.#balance;
  }
  
  set balance(value) {
    if (value < 0) throw new Error("Balance cannot be negative");
    this.#balance = value;
  }
}
"""

6. 模块和包

6.1 导入模块

python
# 导入整个模块
import math
print(math.pi)      # 3.141592653589793
print(math.sqrt(16)) # 4.0

# 导入特定函数
from math import pi, sqrt
print(pi)
print(sqrt(16))

# 导入并重命名
import numpy as np
from datetime import datetime as dt

# 导入所有(不推荐)
from math import *

# Dify 中的实际例子
from flask import Flask, request, jsonify
from typing import Optional, List, Dict
from pydantic import BaseModel, Field

6.2 创建模块

python
# 文件:utils.py
"""工具函数模块"""

def add(a, b):
    """加法"""
    return a + b

def multiply(a, b):
    """乘法"""
    return a * b

class Calculator:
    """计算器类"""
    @staticmethod
    def add(a, b):
        return a + b

# 模块级变量
PI = 3.14159

# 文件:main.py
from utils import add, Calculator
import utils

result1 = add(2, 3)
result2 = Calculator.add(5, 7)
result3 = utils.multiply(4, 6)

6.3 包结构

python
# 包结构(Dify 实际例子)
"""
api/
├── __init__.py
├── core/
│   ├── __init__.py
│   ├── model_runtime/
│   │   ├── __init__.py
│   │   ├── model_manager.py
│   │   └── entities/
│   │       ├── __init__.py
│   │       └── model.py
│   └── rag/
│       ├── __init__.py
│       └── retrieval.py
└── services/
    ├── __init__.py
    └── app_service.py
"""

# 导入方式
from api.core.model_runtime import ModelManager
from api.core.rag.retrieval import Retriever
from api.services.app_service import AppService

# 相对导入
from . import model_manager
from .. import rag
from ...services import app_service

7. 异常处理

python
# try-except(类似 JS 的 try-catch)
try:
    result = 10 / 0
except ZeroDivisionError as e:
    print(f"Error: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")
else:
    print("No exceptions occurred")
finally:
    print("This always executes")

# 抛出异常
def validate_age(age):
    if age < 0:
        raise ValueError("Age cannot be negative")
    if age > 150:
        raise ValueError("Age too large")
    return age

# 自定义异常
class InvalidUserError(Exception):
    """自定义异常"""
    pass

def create_user(name):
    if not name:
        raise InvalidUserError("Name cannot be empty")
    return {"name": name}

# Dify 中的例子
from werkzeug.exceptions import BadRequest, NotFound

try:
    user = get_user(user_id)
    if not user:
        raise NotFound("User not found")
except NotFound:
    return jsonify({"error": "User not found"}), 404
except Exception as e:
    return jsonify({"error": str(e)}), 500

8. 实践项目

项目 1:用 Python 重写 JS 工具函数

python
# 1. debounce 函数
import time
from functools import wraps

def debounce(wait):
    """防抖装饰器"""
    def decorator(func):
        last_called = [0]
        
        @wraps(func)
        def wrapper(*args, **kwargs):
            current = time.time()
            if current - last_called[0] >= wait:
                last_called[0] = current
                return func(*args, **kwargs)
        return wrapper
    return decorator

# 2. deep_clone 函数
import copy

def deep_clone(obj):
    """深拷贝对象"""
    return copy.deepcopy(obj)

# 3. flatten 数组
def flatten(arr):
    """扁平化数组"""
    result = []
    for item in arr:
        if isinstance(item, list):
            result.extend(flatten(item))
        else:
            result.append(item)
    return result

# 测试
nested = [1, [2, 3, [4, 5]], 6]
print(flatten(nested))  # [1, 2, 3, 4, 5]

# 4. 实现一个简单的 Promise(使用 asyncio)
import asyncio

async def fetch_data(url):
    """模拟异步获取数据"""
    await asyncio.sleep(1)  # 模拟延迟
    return f"Data from {url}"

async def main():
    result = await fetch_data("https://api.example.com")
    print(result)

# asyncio.run(main())

项目 2:阅读 Dify 的 helper.py

打开并分析 /Users/zhangjinhe/Documents/my/codes/dify/api/libs/helper.py

python
# 找出以下内容:
# 1. 使用了哪些 Python 特性?
# 2. 函数参数是如何定义的?
# 3. 类型提示是如何使用的?
# 4. 异常处理的模式是什么?
# 5. 有哪些工具函数可以学习?

# 示例分析:
def generate_text_hash(text: str) -> str:
    """
    Generate a hash for the given text.
    Uses SHA-256 hashing.
    """
    import hashlib
    hash_object = hashlib.sha256(text.encode())
    return hash_object.hexdigest()

9. 思考题

  1. 类型系统:Python 的类型提示(Type Hints)和 TypeScript 的类型系统有什么区别?
  2. 列表推导式:将以下 JS 代码改写为 Python 列表推导式:
    javascript
    const result = arr
      .filter(x => x > 0)
      .map(x => x * 2)
      .slice(0, 10);
  3. 装饰器预习:查阅 Python 装饰器的概念,思考它和 JS 装饰器的区别
  4. 异常处理:为什么 Python 使用 try-except 而 JS 使用 try-catch
  5. 鸭子类型:理解"如果它走起来像鸭子,叫起来像鸭子,那么它就是鸭子"这句话在 Python 中的含义

10. 检查清单

完成本节后,你应该能够:

  • [ ] 使用 Python 基础语法编写程序
  • [ ] 理解 Python 和 JavaScript 的主要差异
  • [ ] 熟练使用列表、字典、元组、集合
  • [ ] 定义函数并使用各种参数类型
  • [ ] 创建类并理解继承
  • [ ] 导入和使用模块
  • [ ] 处理异常
  • [ ] 阅读 Dify 中的 Python 代码

11. 下一步

完成本节后,继续学习:

12. 参考资源