Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Context Variables ใน Python

Context Variables คือตัวแปรที่มีค่าแตกต่างกันไปตาม Context (บริบท) ต่างจาก Thread-Local Storage ที่แต่ละ Thread มีค่าแยกกัน Context Variable อาจมีหลาย Context ใน Thread เดียวกัน เหมาะสำหรับติดตามตัวแปรใน Asynchronous Concurrent Tasks

คลาส ContextVar

ใช้สำหรับประกาศและทำงานกับ Context Variables


import contextvars
name = contextvars.ContextVar("name", default='Hello')

พารามิเตอร์ default จะถูกคืนค่าโดย ContextVar.get() เมื่อไม่พบค่าใน Context ปัจจุบัน

Properties

  • name: ชื่อของตัวแปร (Read-only)

Methods

Methodคำอธิบาย
get(default=None)คืนค่าของตัวแปรใน Context ปัจจุบัน ถ้าไม่มี: คืน default argument, หรือ default ของ ContextVar, หรือ Raise LookupError
set(value)ตั้งค่าใหม่สำหรับตัวแปรใน Context ปัจจุบัน คืนค่า Token
reset(token)คืนค่าเดิมก่อน set() ที่สร้าง Token นั้น

คลาส Context

Mapping ของ ContextVars ไปยังค่าของพวกเขา

  • Context(): สร้าง Context ว่าง
  • copy_context(): คัดลอก Context ปัจจุบัน

Method run()


context.run(callable, *args, **kwargs)

รัน callable ใน Context object นี้ การเปลี่ยนแปลง Context Variables จะอยู่ใน Context นี้ Raise RuntimeError ถ้าเรียกจากหลาย OS Thread หรือ Recursive

Methods อื่นๆ

Methodคำอธิบาย
copy()Shallow copy ของ Context object
context[var]คืนค่าของ ContextVar var (Raise KeyError ถ้าไม่มี)
get(var, default=None)คืนค่าของ var ถ้ามี ไม่งั้นคืน default (หรือ None)
__iter__()Iterator over variables ใน Context
__len__()จำนวน Variables ใน Context
keys()List ของ Variables ทั้งหมด
values()List ของค่าทั้งหมด
items()List ของ (var, value) pairs

ตัวอย่างการใช้งาน


import contextvars
import asyncio

request_id = contextvars.ContextVar('request_id')

async def handle_request(req_id):
    request_id.set(req_id)
    await process_request()

async def process_request():
    print(f"Processing request {request_id.get()}")

async def main():
    await asyncio.gather(
        handle_request('req-1'),
        handle_request('req-2'),
        handle_request('req-3'),
    )

asyncio.run(main())

ผลลัพธ์


Processing request req-1
Processing request req-2
Processing request req-3

แต่ละ Task มี request_id ของตัวเอง แม้รันใน Thread เดียวกัน (asyncio)

เมื่อไหร่ควรใช้

  • Async/await code ที่ต้องการส่งผ่านค่าระหว่าง Call stack
  • Logging/Tracing ที่ต้องการ Request ID, User ID ตาม Context
  • Database connection pooling ต่อ Context
  • Configuration ที่เปลี่ยนตาม Request/User