定义一个类
class Person:
    # 构造函数(初始化方法)
    def __init__(self, name, age):
        self.name = name  # 实例属性
        self.age = age

    # 实例方法
    def greet(self):
        return f"你好,我是{self.name},今年{self.age}岁。"

    # 类方法(使用 @classmethod 装饰器)
    @classmethod
    def from_birth_year(cls, name, birth_year):
        current_year = 2026  # 可以根据需要动态获取当前年份
        age = current_year - birth_year
        return cls(name, age)

    # 静态方法(使用 @staticmethod 装饰器)
    @staticmethod
    def is_adult(age):
        return age >= 18

# 使用示例
p1 = Person("张三", 25)
print(p1.greet())  # 输出:你好,我是张三,今年25岁。

p2 = Person.from_birth_year("李四", 2000)
print(p2.greet())  # 输出:你好,我是李四,今年26岁。

print(Person.is_adult(20))  # 输出:True
继承示例

简单说就是类的大括号里写了类,就表示继承。

要点:
1、语法 class SubClass(ParentClass):
class Dog(Animal): 表示 Dog 类继承自 Animal 类。Dog 自动拥有了 Animal 中定义的 init (如果不重写)、info 等方法。

2、super().init(…)
在子类的 init 中,我们通常需要先调用父类的初始化方法,以确保父类定义的属性(如 name, age)被正确设置。
super() 是一个内置函数,返回父类的临时对象。使用它比直接写 Animal.init(self, …) 更灵活,特别是在多重继承时。

3、方法重写 (Overriding)
父类 Animal 有 speak() 方法,但返回的是通用声音。
子类 Dog 和 Cat 重新定义了 speak() 方法。当调用 my_dog.speak() 时,Python 会优先执行子类中定义的版本,而不是父类的。这就是多态的基础。

4、扩展功能
子类可以拥有父类没有的新属性(如 breed, color)和新方法(如 fetch, climb_tree)。

代码:

# 1. 定义父类 (基类)
class Animal:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def speak(self):
        return "Some generic animal sound..."

    def info(self):
        return f"我是 {self.name},今年 {self.age} 岁。"


# 2. 定义子类 (派生类) - 继承自 Animal
class Dog(Animal):
    def __init__(self, name, age, breed):
        # 调用父类的构造函数,初始化 name 和 age
        # super() 代表父类 (Animal)
        super().__init__(name, age)
        self.breed = breed  # 这是 Dog 特有的属性

    # 方法重写 (Override): 修改父类的方法行为
    def speak(self):
        return "汪汪汪!"

    # 新增方法: 子类特有的功能
    def fetch(self):
        return f"{self.name} 正在捡球..."


# 3. 定义另一个子类
class Cat(Animal):
    def __init__(self, name, age, color):
        super().__init__(name, age)
        self.color = color

    # 方法重写
    def speak(self):
        return "喵喵喵~"

    def climb_tree(self):
        return f"{self.name} 正在爬树..."


# --- 使用示例 ---

# 创建一个狗对象
my_dog = Dog("旺财", 3, "金毛")
print(my_dog.info())  # 输出: 我是 旺财,今年 3 岁。 (继承自 Animal)
print(my_dog.speak())  # 输出: 汪汪汪! (重写了 Animal 的 speak)
print(my_dog.fetch())  # 输出: 旺财 正在捡球... (Dog 特有的方法)
print(f"品种: {my_dog.breed}")

print("-" * 30)

# 创建一个猫对象
my_cat = Cat("咪咪", 2, "白色")
print(my_cat.info())  # 输出: 我是 咪咪,今年 2 岁。 (继承自 Animal)
print(my_cat.speak())  # 输出: 喵喵喵~ (重写了 Animal 的 speak)
print(my_cat.climb_tree())  # 输出: 咪咪 正在爬树... (Cat 特有的方法)

# 验证类型
print(isinstance(my_dog, Dog))  # True
print(isinstance(my_dog, Animal))  # True (狗也是动物)
是否可以多继承呢?

可以,代码:

# 多重继承:同时继承 Item 和 TimestampMixin
class EnhancedItemRequest(Item, TimestampMixin):
    quantity: int

__init__是什么意思?

__init__主要为了简化导入。
如果一个文件夹加了__init__.py,表示这个文件夹是一个包,可以被import导入。

但是直接导入还是会报错,需要:
1、文件夹下创建__init__.py文件。
2、定义__all__属性,配置公开的类。

from .config import settings
__all__ = [
    "settings"
]

3、其他python文件就可以简化导入该包的类了。

不用__init__:
import core.config import settings

用__init__:
import core import settings

注:不但可以导入类,也可以导入属性。

接口

1、接口类的括号里必须是Protocol
2、实现类不用显示实现,只要方法名一样就行。

from typing import Protocol

class Car(Protocol):
  def run(self):
      pass

class BENZ():
  def run(self):
      print("Benz is running")

方法定义

在python中,方法定义非常重要,很灵活,所以需要好好掌握。

方法定义中…是什么意思?如def upload(file: UploadFile = File(…))

代码:

def upload(file:  UploadFile = File(...))

如下表:

写法 描述
file: UploadFile = File(…) 必填 且 参数校验
file: UploadFile = File(None) 非必填
file: Optional[UploadFile] =None 非必填
file: Optional[UploadFile] 非必填(不会报错,但是不推荐这么写)
方法定义-参数
参数类型 必填写法示例 说明
查询参数 param: str = Query(...) 强制客户端在 URL 中提供该参数。
路径参数 param: int = Path(...) 虽然路径参数默认必填,但此写法可添加校验规则。
文件参数 file: UploadFile = File(...) 强制客户端在表单中上传文件。
请求体 item: Item 整个对象为必填,字段是否必填由 Pydantic 模型内部定义。
参数 *args, **kwargs 有什么区别?

好问题。
*args 用于接收任意数量的位置参数(没有名字的值),并将它们打包成一个元组 (tuple)。
**kwargs 用于接收任意数量的关键字参数(有名字的值,即 key=value 形式),并将它们打包成一个字典 (dict)。

既然是key value为什么不叫kvargs呢?
是这样,kwargs是关键字参数(keyword args),所以是kw而不是kv。

return可以返回多个参数(元组)

这确实有点强了,不用像java必须返回一个对象(对象、数据、集合等),python直接就能返回多对象。

方法定义-这句话是什么意思?

一个看似很简单的问题,把我问住了,仔细学习下。


代码:
def check_order_amount(state: State) -> Command[Literal["auto_approve", "manual_review"]]


解释:
1(state: State):
意思是这个函数接收一个参数,名字叫 state,并且这个参数的类型必须是 State(也就是你前面定义好的全局状态)。
2->(箭头):
这个箭头在 Python 函数定义中,专门用来表示“这个函数会返回什么类型的东西”。
3、Command[...]:
意思是这个函数的返回值必须是一个 Command 对象(也就是 LangGraph 里的“指挥官”)。
4、Literal["auto_approve", "manual_review"](这是最核心的部分):
Literal 是 Python 里的一个特殊类型,意思是“字面量”。它在这里给 Command 里的 goto 跳转路径做了极其严格的限制。
整句话连起来的意思是:这个函数返回的 Command,它的 goto 属性只能填写 "auto_approve" 或者 "manual_review" 这两个字符串,填其他的都会报错!
depends
depends的参数有几种形式?

有3种。
1、方法名
2、类对象 # 会执行__init__方法,返回该对象
3、类实例对象 # 如果一个类定义了__call__方法,那么它的实例也是可以调用的

注:__call__这种机制,不只是depends有用到,在fastapi的middleware中也有用到。

depends的参数可以没有返回值吗?

可以,只用于执行不用于返回。

成员变量、静态成员变量(静态变量)、局部变量

成员变量

1、必须在__init__方法里
2、必须用selft修饰
定义:

class User:
    def __init__(self):
        # 这才是 实例成员变量,对标 Java private 实例成员
        self.name = ""
        self.age = 18

使用:

类内部使用:
def list:
		return self.name;

外部调用:
user = User()
printf(user.name)
静态变量

和java是有区别的,java需要用static修饰,python直接定义在类里面的就是静态变量。

定义:

class User:
	  # 这就相当于java的静态变量
    name = ""
    age = 18

使用:

printf(User.age)
局部变量

和java一致,方法中的参数属于局部变量,代码略。

->这个箭头表示函数会返回什么东西

。。。居然是这样

类型提示(type hints)

注:类型提示运行的时候并不会执行。

示例代码:

# 基础类型标注
name: str ="lishimin"
double1: float = 0.01
success: bool = True

# 列表、字典、元组
from typing import List
arr: List[int] = [1, 2, 3]
arr2: list[int] = [1, 2, 3] # 这种写法,连import List都不用写

score_map: dict [str, int] = {"Alice": 95, "Bob": 88} # 分数

coordinates: tuple[float, float] = (39.9, 116.4) # 坐标,经纬度
类型提示的作用

前面说了,类型提示在执行的时候不会运行,那么它有什么作用呢?

有的,作用主要有两个。
1、类似说明书,易于阅读
2、编译器可以读取到,自动提示时更加准确和方便

@staticmethod的作用?

和java static类似,修改的方法属于类而非实例。

注:和java有一点区别,java中静态变量只能类来调用,实例不能调用。python中实例也可以调用,但是不推荐。

代码:

class MathUtils:
    """一个数学工具类"""

    @staticmethod
    def add(a, b):
        """一个简单的加法工具函数"""
        return a + b

    @staticmethod
    def is_positive(num):
        """判断一个数是否为正数"""
        return num > 0

# --- 调用方式 ---

# 1. 通过类名直接调用 (推荐方式)
result1 = MathUtils.add(5, 3)
print(result1)  # 输出: 8

is_pos = MathUtils.is_positive(10)
print(is_pos)   # 输出: True


# 2. 通过实例调用 (可行但不推荐,因为该方法并不依赖实例)
utils = MathUtils()
result2 = utils.add(10, 20)
print(result2)  # 输出: 30
cls和@classmethod

在jsonResult实体类看到cls没明白什么意思。
这个属于限定情况,当@classmethod注解时,方法的第一个参数表示类本身,即cls。这个也属于特定写法,如果不传cls,那么参数接的不正确

表示什么意思,例如state?

**表示解包语法。例如:

return {
        **state,
        "decision": decision
    }

原始报文:

state = {
    "order_id": 101,
    "status": "paid",
    "message": "正在处理"
}
decision = "reject"

使用**state相当于:

{
    "order_id": 101,  # 保留了
    "status": "paid", # 保留了
    "message": "正在处理", # 保留了
    "decision": "reject"   # 新增/更新了
}

看到了吧,这样写比较方便。

pass关键字

pass的作用只有一个,就是让空方法不报错。代码:

# 方法没有任何内容 报错
def method1():

# 加了pass 不报错
def method2():
    pass

# 方法有内容不报错 不报错
def method3():
    print("111")

# pass不影响执行
def method4():
    pass
    print("1")
    print("2")

method4()
new关键字

python没有new关键字。
创建对象的时候类名传入参数即可。

user = User(id=1, name="张三") # 不需要new

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐