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代替null和undefined - 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]) # True2. 数据结构
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, Field6.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_service7. 异常处理
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)}), 5008. 实践项目
项目 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. 思考题
- 类型系统:Python 的类型提示(Type Hints)和 TypeScript 的类型系统有什么区别?
- 列表推导式:将以下 JS 代码改写为 Python 列表推导式:javascript
const result = arr .filter(x => x > 0) .map(x => x * 2) .slice(0, 10); - 装饰器预习:查阅 Python 装饰器的概念,思考它和 JS 装饰器的区别
- 异常处理:为什么 Python 使用
try-except而 JS 使用try-catch? - 鸭子类型:理解"如果它走起来像鸭子,叫起来像鸭子,那么它就是鸭子"这句话在 Python 中的含义
10. 检查清单
完成本节后,你应该能够:
- [ ] 使用 Python 基础语法编写程序
- [ ] 理解 Python 和 JavaScript 的主要差异
- [ ] 熟练使用列表、字典、元组、集合
- [ ] 定义函数并使用各种参数类型
- [ ] 创建类并理解继承
- [ ] 导入和使用模块
- [ ] 处理异常
- [ ] 阅读 Dify 中的 Python 代码
11. 下一步
完成本节后,继续学习: