σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft Academy学习路线
Ctrl K
AO
+1.2k 位学习者
登录加入 ↗
学习路线
AO
+1.2k 位学习者
登录
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Python 学习路线›模块 1 · 面向量化的 Python 基础›主题 1.19·~45分钟入门

异常与错误处理

路线进度模块 1/11 · 主题 19/33
1.19 异常与错误处理
—实验得分— / 100总 XP—连续天数—

当出现问题时

当 Python 无法完成你的要求时,它会引发异常:float("abc") 引发 ValueError,{}["x"] 引发 KeyError,1 / 0 引发 ZeroDivisionError,打开不存在的文件引发 FileNotFoundError。如果没有人处理,程序就会停止并打印回溯(traceback),即导致错误的调用链,从下往上读。对真正的 bug 来说,这就是正确的结果。对于可以预料的问题,比如用户输入了错误的价格,则用 try 和 except 来处理。

# Handle an expected problem
def to_price(text):
    try:
        return float(text)
    except ValueError:
        return None

print(to_price("184.25"))  # 184.25
print(to_price("abc"))     # None

# An unhandled one stops the program with a traceback
# print(int("abc"))        # ValueError: invalid literal for int()...

只捕获你预期的异常

要写明异常类型:except ValueError:。单独的 except: 或 except Exception: 还会吞掉你本不想隐藏的 bug,例如传入 None 引起的 TypeError,程序就会带着错误数据继续运行。多个类型可以共用一个处理器 except (ValueError, KeyError):,也可以分别处理。Python 按顺序尝试处理器,执行第一个匹配的。用 except ValueError as error: 可以保留错误并查看它。

# Specific handlers, tried in order
def read_quantity(text):
    try:
        return int(text)
    except ValueError as error:
        print("not a whole number:", error)
        return 0
    except TypeError:
        print("expected text, got something else")
        return 0

print(read_quantity("200"))  # 200
print(read_quantity("2.5"))  # prints the message, then 0
print(read_quantity(None))   # prints the message, then 0

else 与 finally

语句还有两个可选部分。else: 仅在 try 块没有引发任何异常时运行,这样有风险的那一行可以保持简短,后续代码也不在保护范围内。finally: 总是运行,无论是否出错,即使在 return 之后也一样:用它做清理工作。很多时候 with 块已经替你做了清理,比如处理文件时。

# else runs on success, finally runs always
def describe(text):
    try:
        price = float(text)
    except ValueError:
        print("bad price")
    else:
        print("price is", price)
    finally:
        print("done with", repr(text))

describe("184.25")
# price is 184.25
# done with '184.25'
describe("abc")
# bad price
# done with 'abc'

引发你自己的异常

当函数收到无法接受的值时,应当用 raise 明确拒绝,而不是悄悄返回错误的结果:raise ValueError("price must be positive")。选择合适的内置类型(类型对但值不好用 ValueError,类型错误用 TypeError),并写出说明问题的消息。之后由调用者决定是否捕获。在 except 块里,单独的 raise 会重新引发刚捕获的错误,当你只想记录它时很方便。

# Refuse bad input, let the caller decide
def parse_price(text):
    price = float(text)           # may raise ValueError itself
    if not price > 0:
        raise ValueError("price must be positive")
    return price

for text in ["184.25", "-5", "abc"]:
    try:
        print(parse_price(text))
    except ValueError as error:
        print("rejected:", error)
# 184.25
# rejected: price must be positive
# rejected: could not convert string to float: 'abc'
不要隐藏你无法修复的错误什么都不做的 except(except: pass)会把本可调试的崩溃变成悄无声息的错误数字,这在交易代码里糟糕得多。只在你知道合理应对方式的地方捕获错误:使用默认值、跳过该项、重试,或报告后停止。否则就让它向上传播到知道该怎么处理的地方。
  • try / except SpecificError:只处理你预期的问题。
  • else 在未引发异常时运行;finally 总是运行。
  • raise ValueError("message") 明确拒绝无效输入。

下一节:模块与导入,如何复用标准库和你自己文件中的代码。

实验:评分内容

  • 用 safe_float 在不崩溃的前提下转换文本25 分
  • 用 parse_price 拒绝无效价格25 分
  • 用 first_valid_price 跳过无效条目25 分
  • 用 read_quantity 处理缺失或损坏的文件25 分
资源管理器 · lab-19-1
▾ lab-19-1
…
bash · 浏览器内
learner@quantcraft:~/lab-19-1$
Python 尚未加载PythonLn 1, Col 1Spaces: 4UTF-8

要重置此主题吗?

lab-19-1 中的所有内容将恢复为初始文件,终端也会被清空。你当前的解答将丢失,且无法撤销。

将被重置
  • main.py → 初始代码
  • 终端历史与测试输出
  • 未提交的更改
将被保留
  • 实验最高得分
  • 你的 XP 与连续天数
  • 讲解进度与笔记

登录后即可运行你的代码。

所有讲解均可免费阅读。创建账户或登录后,即可运行代码、运行测试并提交此实验。

  • 浏览器内 IDE 与 bash 终端,无需安装
  • 即时评分、XP 以及你在学习路线中的位置
创建账户登录
或
使用 GitHub 继续