0Pricing
Python Academy · บทเรียน

functools: partial และ reduce

สร้างฟังก์ชันเฉพาะทางด้วย partial และพับลำดับข้อมูลด้วย reduce

functools: partial และ reduce เป็นบทเรียน Python Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Python Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน

ภาพรวม functools

functools เป็นโมดูลในไลบรารีมาตรฐานที่รวมฟังก์ชันระดับสูง ซึ่งทำงานกับฟังก์ชันอื่นหรือคืนค่าฟังก์ชันอื่น

import functools

# partial, reduce, lru_cache, wraps, cached_property ...
print(dir(functools))

partial()

functools.partial(func, *args, **kw) สร้างฟังก์ชันที่เรียกใช้ได้ใหม่ โดยกำหนดอาร์กิวเมนต์บางส่วนไว้ล่วงหน้า

import functools

def power(base, exp):
    return base ** exp

square = functools.partial(power, exp=2)
cube   = functools.partial(power, exp=3)

print(square(4))  # 16
print(cube(3))    # 27

partial กับเมธอด

ใช้ partial เพื่อปรับเมธอดที่มีพารามิเตอร์คงที่ให้ใช้เป็นฟังก์ชันเรียกกลับหรือเครื่องจัดการเหตุการณ์ได้

import functools, logging

logger = logging.getLogger("app")
log_error = functools.partial(logger.log, logging.ERROR)

log_error("Something went wrong")

partial เทียบกับ lambda

ควรใช้ partial แทน lambda เมื่อต้องกำหนดอาร์กิวเมนต์ล่วงหน้า เพราะสามารถจัดเก็บด้วย pickle ได้ มีการแสดงผลแทนที่ดี และคงคำอธิบายฟังก์ชันไว้

import functools

mul = lambda x, y: x * y

double_lambda = lambda x: mul(x, 2)            # lambda approach
double_partial = functools.partial(mul, y=2)   # partial approach

print(double_partial(5))   # 10

reduce()

functools.reduce(func, iterable, initial) รวมสะสมตัววนซ้ำจากซ้ายไปขวาโดยใช้ฟังก์ชันแบบทวิภาค

import functools, operator

total = functools.reduce(operator.add, [1,2,3,4,5])
print(total)   # 15

product = functools.reduce(operator.mul, [1,2,3,4,5], 1)
print(product) # 120

การสร้าง max() ด้วย reduce

สาธิต reduce ด้วยการสร้าง max() ขึ้นใหม่:

import functools

def my_max(seq):
    return functools.reduce(lambda a, b: a if a > b else b, seq)

print(my_max([3, 1, 4, 1, 5, 9]))  # 9

การคลี่รายการซ้อนกัน

ใช้ reduce ร่วมกับ operator.iconcat เพื่อคลี่โครงสร้างที่ซ้อนกันออกหนึ่งระดับ

import functools, operator

nested = [[1,2],[3,4],[5]]
flat = functools.reduce(operator.iconcat, nested, [])
print(flat)  # [1, 2, 3, 4, 5]

partial สำหรับการสร้าง URL

รูปแบบการใช้ partial ที่นำไปใช้ได้จริงคือ กำหนด URL ฐานไว้ แล้วสร้างตัวช่วยส่งคำขอเฉพาะทาง

import functools, urllib.request

def fetch(base, path):
    url = base.rstrip("/") + "/" + path.lstrip("/")
    with urllib.request.urlopen(url) as r:
        return r.read()

github = functools.partial(fetch, "https://api.github.com")
# github("/users/octocat")

wraps(): การคงข้อมูลเมทาดาทา

เมื่อเขียน decorator ให้ใช้ @functools.wraps(wrapped) เพื่อให้ wrapper คงชื่อและคำอธิบายฟังก์ชันเดิมไว้

import functools

def decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        return func(*args, **kw)
    return wrapper

@decorator
def greet(name):
    """Say hello."""
    return f"Hello, {name}"

print(greet.__name__)  # greet
print(greet.__doc__)   # Say hello.

total_ordering

@functools.total_ordering เติมเมธอดเปรียบเทียบที่ขาดหายไป เมื่อกำหนด __eq__ และหนึ่งใน __lt__/__le__/__gt__/__ge__

import functools

@functools.total_ordering
class Version:
    def __init__(self, major, minor):
        self.v = (major, minor)
    def __eq__(self, o): return self.v == o.v
    def __lt__(self, o): return self.v < o.v

print(Version(1,2) >= Version(1,1))  # True

singledispatch

@functools.singledispatch สร้างฟังก์ชันที่เลือกใช้การติดตั้งใช้งานต่างกันตามชนิดของอาร์กิวเมนต์ตัวแรก

import functools

@functools.singledispatch
def process(arg):
    raise NotImplementedError(type(arg))

@process.register(int)
def _(n): return n * 2

@process.register(str)
def _(s): return s.upper()

print(process(5))     # 10
print(process("hi"))  # HI

ตรวจสอบอย่างรวดเร็ว

functools.partial(pow, 2) สร้างอะไร

สรุปทบทวน

partial กำหนดอาร์กิวเมนต์ของฟังก์ชันไว้ล่วงหน้า reduce รวมสะสมลำดับด้วยฟังก์ชันแบบทวิภาค wraps คงข้อมูลเมทาดาทาของ decorator total_ordering เติมเมธอดเปรียบเทียบ และ singledispatch เลือกการทำงานตามชนิด

คำถามที่พบบ่อย

บทเรียน “functools: partial และ reduce” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “functools: partial และ reduce” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Python Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “functools: partial และ reduce”

สร้างฟังก์ชันเฉพาะทางด้วย partial และพับลำดับข้อมูลด้วย reduce คุณปฏิบัติ Python Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Python Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Python Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “functools: partial และ reduce” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Python Academy นี้ได้ไหม

ได้ บทเรียน Python Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. itertools: ตัววนซ้ำแบบไม่สิ้นสุดและมีขอบเขต
  2. itertools: การจัดแบบเชิงการนับ
  3. functools: partial และ reduce
  4. functools: lru_cache และ cached_property
← กลับไปที่ Python Academy