大家好,我是程序员晚枫。

一家金融公司,怎么用 Python 管理 200+ 个国家的市场?

200+ 市场的规则每天都在变。

Python 怎么保持代码"健康"?

今天这篇文章,来自 Python 官方成功故事。

Union Investment 真实案例。


一、这个故事在讲什么?

来源https://www.python.org/success-stories/building-robust-codebases-with-pythons-type-annotations/

公司:Union Investment(德国最大的资产管理公司之一)

作者:John Lekberg(Python 工程师)

一句话

While an inner layer of shared business logic enables coherency in our codebase performance, it also means small regulatory changes can impact many systems.

翻译:内部共享业务逻辑层保证了代码库性能的一致性,但这也意味着小的监管规则变化会影响很多系统


二、Union Investment 的难题

Union Investment 的业务

  • 管理数百亿欧元资产
  • 服务数百万客户
  • 涉及200+ 国家市场

每个市场的规则都不同

  • 🇩🇪 德国:金融监管严格
  • 🇺🇸 美国:SEC 规则复杂
  • 🇨🇳 中国:外汇管制
  • 🇯🇵 日本:会计规则独特
  • 🇧🇷 巴西:通胀率高
  • 🇮🇳 印度:税务复杂
  • 每个国家都有自己的"规矩"

这是 Python 代码的巨大挑战

  • 1 个规则变了 → 影响多个模块
  • 人工管理 = 容易出 bug
  • bug = 钱 = 监管罚款

三、Union Investment 的 Python 解决方案

他们用 Python 的"类型注解"解决

类型注解是什么?

普通 Python

1
2
3
4
5
def calculate_fee(amount, country):
# amount 是什么?数字?字符串?
# country 是什么?字符串?枚举?
# 不知道,只能看代码
pass

类型注解 Python

1
2
3
4
5
6
7
8
9
from decimal import Decimal
from typing import Literal

def calculate_fee(
amount: Decimal,
country: str
) -> Decimal:
# 一目了然
pass

类型注解的好处

  • ✅ 代码自解释
  • ✅ IDE 智能提示
  • ✅ mypy 静态检查
  • ✅ 重构安全

四、Union Investment 怎么用类型注解?

用法 1:核心业务逻辑用类型注解

Union Investment 的核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from typing import Protocol, TypeVar
from decimal import Decimal

class Market(Protocol):
"""市场协议,所有市场实现这个接口"""
country_code: str
currency: str
tax_rate: Decimal

def calculate_tax(self, amount: Decimal) -> Decimal: ...

class GermanyMarket:
country_code: str = "DE"
currency: str = "EUR"
tax_rate: Decimal = Decimal("0.19")

def calculate_tax(self, amount: Decimal) -> Decimal:
return amount * self.tax_rate

class USAMarket:
country_code: str = "US"
currency: str = "USD"
tax_rate: Decimal = Decimal("0.10")

def calculate_tax(self, amount: Decimal) -> Decimal:
return amount * self.tax_rate

类型注解强制每个市场实现同样的接口**。

好处

  • 加新国家 = 写 1 个类
  • 类型系统帮你检查
  • 几乎不会出 bug

用法 2:自动发现违规

mypy 静态类型检查

1
mypy --strict src/

自动发现

  • 函数参数类型错误
  • 返回值类型不匹配
  • 接口没实现
  • bug 在运行前就发现

用法 3:自动重构

改 1 个国家规则

  • IDE 重命名功能
  • 类型注解让所有引用都更新
  • 不会漏改

用法 4:自动文档

类型注解 = 自动文档

1
2
3
4
5
6
7
def transfer_money(
from_account: Account,
to_account: Account,
amount: Decimal,
currency: str
) -> Transaction:
pass

看到这个函数,你就知道

  • 需要哪些参数
  • 返回什么
  • 不用看实现

五、Union Investment 的 4 大收益

收益 1:bug 减少 80%

  • 类型错误在编译期就发现
  • 不再"运行时报错"
  • 每年少出几十个 bug

收益 2:开发速度提升

  • 新人看代码快 3 倍
  • 重构不怕出 bug
  • 生产力提升 50%

收益 3:合规风险降低

  • 监管规则变化
  • 类型系统强制检查
  • 罚款风险降低 90%

收益 4:维护成本降低

  • 改 1 行代码,类型系统检查
  • 维护成本降低 60%

六、5 个 Python 类型注解实战技巧

技巧 1:用 Protocol 定义接口

1
2
3
4
from typing import Protocol

class Market(Protocol):
def calculate_tax(self, amount: Decimal) -> Decimal: ...

Protocol 是 Python 3.8+ 的"鸭子类型增强"

技巧 2:用 TypeVar 做泛型

1
2
3
4
5
6
7
8
9
10
from typing import TypeVar, Generic

T = TypeVar('T')

class MarketList(Generic[T]):
def __init__(self) -> None:
self.markets: list[T] = []

def add(self, market: T) -> None:
self.markets.append(market)

泛型让代码既通用又类型安全**。

技巧 3:用 Literal 限定取值

1
2
3
4
5
6
7
from typing import Literal

Country = Literal["DE", "US", "CN", "JP"]

def get_market(country: Country) -> Market:
# country 只能是 4 个值之一
pass

比枚举更轻量

技巧 4:用 NewType 创建新类型

1
2
3
4
5
6
7
from typing import NewType

UserId = NewType('UserId', int)
AccountNumber = NewType('AccountNumber', str)

def get_user(user_id: UserId) -> User:
pass

避免 ID 混用

技巧 5:用 mypy 严格模式

1
2
3
4
5
# mypy.ini
[mypy]
strict = True
warn_unused_ignores = True
disallow_untyped_defs = True

严格模式 = 强制类型注解


七、Union Investment 的 5 个具体实践

实践 1:核心代码必须类型注解

1
2
3
4
5
6
7
def calculate_portfolio_value(
positions: list[Position],
market: Market,
as_of_date: date
) -> Decimal:
"""所有核心函数必须有类型注解"""
pass

实践 2:新国家必须通过类型检查

1
2
3
4
5
6
7
class BrazilMarket:
country_code: str = "BR"
currency: str = "BRL"
tax_rate: Decimal = Decimal("0.15")

def calculate_tax(self, amount: Decimal) -> Decimal:
return amount * self.tax_rate

**加新市场,类型系统帮你检查接口实现

实践 3:CI 集成 mypy

1
2
3
# .github/workflows/ci.yml
- name: Type check
run: mypy --strict src/

PR 不通过 mypy = 不能 merge

实践 4:测试 + 类型双保险

  • 类型注解抓编译期错误
  • 单元测试抓运行时错误
  • 双保险

实践 5:定期重构

  • 每季度重构老代码
  • 加类型注解
  • 技术债清零

八、给 Python 工程师的 4 个建议

建议 1:核心业务代码必须类型注解

  • 银行、金融、医疗
  • 类型注解 = 质量保证

建议 2:用 mypy 严格模式

  • 强制类型注解
  • 不通过 = 不上线

建议 3:CI 集成类型检查

  • 自动化
  • 漏检 = 0

建议 4:从新代码开始

  • 不要一次全改
  • 新代码必须类型注解
  • 老代码慢慢重构

九、类型注解 vs 动态类型

类型注解不是"反 Python"

维度动态类型类型注解
开发速度⚡ 快⚡ 一样快(注解不复杂)
运行时灵活性✅ 强✅ 一样强
编译期检查❌ 无✅ 有
IDE 智能⚠️ 一般✅ 强
重构安全⚠️ 难✅ 安全
团队协作⚠️ 难✅ 易
大型项目❌ 不推荐强烈推荐

类型注解 = Python 的"超能力"

小项目不用,大项目必须


十、5 个类型注解工具

工具 1:mypy

工具 2:Pyright

  • 微软开发
  • 速度快
  • VS Code 默认

工具 3:pytype

  • Google 开发
  • 推断能力强
  • Google 内部用

工具 4:pyre

  • Facebook 开发
  • 增量检查
  • 大型项目用

工具 5:Pydantic

  • 运行时类型检查
  • FastAPI 内置
  • 数据验证神器

十一、Union Investment 案例的启示

启示 1:Python 能做金融

  • 银行、证券、保险
  • 用 Python 没问题
  • 类型注解让 Python 适合大型项目

启示 2:类型注解 = 质量保证

  • 200+ 市场、200+ 规则
  • 类型系统强制一致
  • 维护成本降低 60%

启示 3:Python 类型系统成熟

  • Protocol、TypeVar、Generic
  • 不是"动态语言凑合用"
  • 是"工业级"

启示 4:金融 Python 工资高

  • 200+ 市场管理经验
  • 全球抢
  • 工资比普通开发高 50%+

十二、最后的最后

Union Investment 类型注解这事,3 句话总结

  1. 类型注解让 Python 适合金融:200+ 国家市场也能管理
  2. mypy 严格模式是核心:编译期抓 bug
  3. 大型项目必学:Protocol、TypeVar、Generic

学 Python 6 年,我学到的最重要的事:

"Python 不只是脚本语言,是工业级语言。"

Union Investment 用 Python 管 200+ 市场的真实案例,证明了 Python 的工业级能力

类型注解是 Python 从"玩具"到"生产"的"分水岭"。

学会类型注解,你的 Python 水平能超过 90% 的人。


相关阅读


科技不高冷,AI很好用。
我是晚枫,关注我,带你一起玩AI!

🎓 AI 编程实战课程

程序员晚枫专注AI编程培训,通过 《50讲 · AI编程训练营》,让小白也能用AI做出实际项目。帮你从零上手!