σμ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›الوحدة 11 · أنظمة الإنتاج والنماذج المتقدمة›الموضوع 11.1·~1 سخبير

تحزيم مكتبة Python

الموضع في المسارالوحدة 11 من 11 · الموضوع 1 من 13
11.1 تحزيم مكتبة Python
—درجة المختبر— / 100إجمالي XP—التتابع—

من مجلد سكربتات إلى مكتبة قابلة للتثبيت

الشيفرة التي تعيش في مجلد سكربتات تعمل على جهاز واحد لشخص واحد إلى يوم يحتاجها فيه شخص آخر أو تحتاجها أنت في بيئة مختلفة. والتغليف (packaging) يحوّل شيفرتك إلى مكتبة لها اسم وإصدار وتبعيات معلنة يستطيع أي أحد تثبيتها بـ pip install. وبه يتشارك فريق مكتبة تسعير دون نسخ ملفات، ويشغّل دفتر بحث ومهمة إنتاج الشيفرة نفسها بالضبط، ويصل إصلاح خلل إلى الجميع عبر رقم إصدار جديد.

# Versions are numbers, not text: compare them as tuples
def parse_version(text):
    parts = [int(part) for part in text.split(".")]
    return tuple(parts + [0] * (3 - len(parts)))

print("1.10" > "1.9")                                # False  as text, "1" < "9" decides it: wrong
print(parse_version("1.10") > parse_version("1.9"))  # True   as numbers (1, 10, 0) is newer than (1, 9, 0)
print(parse_version("2"))                            # (2, 0, 0)

البنية وpyproject.toml والبناء

تضع البنية الشائعة الشيفرة في src/yourlib/ (مع __init__.py) والاختبارات في tests/ وملف pyproject.toml في الجذر. وهذا الملف الوحيد يسمّي أداة البناء (جدول [build-system]) ويصف المشروع: name وversion ووصفًا وإصدارات بايثون المدعومة وdependencies. ويثبّت pip install -e . المجلد بوضع قابل للتحرير أثناء التطوير فتسري التعديلات فورًا؛ وينتج python -m build ملف wheel (.whl جاهزًا للتثبيت) وsdist (أرشيف المصدر) في dist/. وضع الإصدار في مكان واحد فقط واعرضه بـ yourlib.__version__ إن احتاجه المستخدمون.

# A minimal pyproject.toml, generated and then read back with tomllib to prove it is valid
import tomllib

def pyproject_toml(name, version, dependencies):
    lines = ["[build-system]", 'requires = ["setuptools>=68"]', 'build-backend = "setuptools.build_meta"', "",
             "[project]", f'name = "{name}"', f'version = "{version}"']
    if dependencies:
        lines += ["dependencies = ["] + [f'    "{d}",' for d in dependencies] + ["]"]
    else:
        lines.append("dependencies = []")
    return "\n".join(lines) + "\n"

text = pyproject_toml("qcpricing", "0.3.0", ["numpy>=1.26", "pandas>=2"])
data = tomllib.loads(text)
print(data["project"]["name"], data["project"]["version"])      # qcpricing 0.3.0
print(data["project"]["dependencies"])                          # ['numpy>=1.26', 'pandas>=2']

الإصدارات ومحددات الإصدار

تتبع معظم المكتبات الإصدار الدلالي: MAJOR.MINOR.PATCH. إصلاح الخلل يزيد الرقم الأخير (1.4.2 إلى 1.4.3) والميزة المتوافقة مع الإصدارات السابقة تزيد الأوسط وتصفّر الأخير (1.5.0) والتغيير الكاسر يزيد الأول (2.0.0). وتُعلن التبعيات بـ محددات: numpy>=1.26,<3 تقبل أي NumPy من 1.26 حتى 3 دون 3. كن مرنًا قدر ما تستطيع بأمانة: حدٌّ أدنى لأقدم إصدار اختبرته وحدٌّ أعلى فقط لإصدار رئيسي تعرف أنه يكسرك. وتثبيت الإصدارات بدقة (==) مكانه ملف القفل في التطبيق لا مكتبة يثبّتها الآخرون.

# Bumping a version and checking a requirement, with versions compared as tuples
import operator

def parse_version(text):
    parts = [int(part) for part in text.split(".")]
    return tuple(parts + [0] * (3 - len(parts)))

def bump_version(version, part):
    major, minor, patch = parse_version(version)
    return {"major": f"{major + 1}.0.0", "minor": f"{major}.{minor + 1}.0", "patch": f"{major}.{minor}.{patch + 1}"}[part]

OPS = {">=": operator.ge, "<": operator.lt, "==": operator.eq}

def satisfies(version, specifier):
    for clause in specifier.split(","):
        symbol = next(op for op in (">=", "==", "<") if clause.startswith(op))
        if not OPS[symbol](parse_version(version), parse_version(clause[len(symbol):])):
            return False
    return True

print(bump_version("1.4.2", "minor"))                # 1.5.0
print(satisfies("1.26.4", ">=1.26,<3"), satisfies("3.0.0", ">=1.26,<3"))      # True False
# One place for the version: read it from the source instead of repeating it in several files
import re

init_py = """__version__ = "0.3.0"
from .pricing import price
"""
match = re.search(r'^__version__ = "([^"]+)"', init_py, re.MULTILINE)
version = match.group(1)
print(version)                                       # 0.3.0
print(tuple(int(part) for part in version.split(".")))      # (0, 3, 0)
انشر بحذرالإصدار وعد: سيعتمد أحدهم غدًا على ذلك الإصدار بعينه فلا يجوز أن يتغير إصدار منشور أبدًا. أصلح الأخطاء بإصدار جديد واحتفظ بسجل تغييرات يقول ما تغير. شغّل الاختبارات على أقدم وأحدث إصدارات بايثون والتبعيات التي تدّعي دعمها. واستعمل فهرسًا خاصًا لشيفرة الاستراتيجية المملوكة ولا تضع في الحزمة مفاتيح أو كلمات مرور أو ملفات بيانات.
  • يمنح التغليف الشيفرة اسمًا وإصدارًا وتبعيات معلنة قابلة للتثبيت بـ pip install؛ طوّر بـ pip install -e . وابنِ بـ python -m build.
  • يحوي pyproject.toml نظام البناء وبيانات [project]؛ قارن الإصدارات كمجموعات أرقام لا كنص أبدًا.
  • استعمل الإصدار الدلالي (MAJOR.MINOR.PATCH) ومحددات مرنة (numpy>=1.26,<3)؛ ولا تغيّر إصدارًا منشورًا أبدًا وأبقِ الأسرار خارج الحزمة.

التالي: CI/CD للشيفرة الكمية، تشغيل الفحوص تلقائيًا عند كل تغيير.

المختبر: ما الذي يُقيَّم

  • قارن الإصدارات كأرقام باستخدام parse_version25 نقطة
  • أصدر الإصدار التالي باستخدام bump_version25 نقطة
  • تحقق من متطلب باستخدام satisfies25 نقطة
  • صِف الحزمة باستخدام pyproject_toml25 نقطة
المستكشف · lab-130-1
▾ lab-130-1
…
bash · داخل المتصفح
learner@quantcraft:~/lab-130-1$
لم يتم تحميل Python بعدPythonLn 1, Col 1Spaces: 4UTF-8

هل تريد إعادة ضبط هذا الموضوع؟

سيعود كل ما في lab-130-1 إلى الملفات الابتدائية وستُمسح الطرفية. ستفقد حلّك الحالي ولا يمكن التراجع عن ذلك.

سيُعاد ضبطه
  • main.py ← الشيفرة الابتدائية
  • سجل الطرفية ومخرجات الاختبارات
  • التغييرات غير المُرسلة
سيُحتفظ به
  • أفضل درجة في المختبر
  • نقاط XP والتتابع
  • تقدّم المحاضرة والملاحظات

سجّل الدخول لتشغيل الكود الخاص بك.

قراءة كل المحاضرات مجانية. أنشئ حسابًا أو سجّل الدخول لتشغيل الكود وتنفيذ الاختبارات وتسليم هذا المختبر.

  • بيئة تطوير داخل المتصفح مع طرفية bash — لا حاجة لتثبيت أي شيء
  • تصحيح فوري ونقاط خبرة ومكانك في المسار
إنشاء حسابتسجيل الدخول
أو
المتابعة عبر GitHub