Python Academy · درس

functools: ‏partial وreduce

أنشئ دوالاً متخصصة باستخدام partial واطوِ التسلسلات باستخدام reduce

الدرس 3 من 413 خطوة

functools: ‏partial وreduce درس مجاني في Python Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 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(): الحفاظ على البيانات الوصفية

عند كتابة مزينات، استخدم @functools.wraps(wrapped) لكي يحافظ الغلاف على اسم الدالة الأصلية وسلسلة توثيقها.

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 على البيانات الوصفية للمزين؛ ويملأ total_ordering أساليب المقارنة؛ ويوجّه singledispatch التنفيذ حسب النوع.

البدء مجانًا

تعلم Python مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
76
الدروس
320

الأسئلة الشائعة

هل درس «functools: ‏partial وreduce» مجاني؟

نعم — نص درس «functools: ‏partial وreduce» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Python Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Python Academy 4 دروس في المجموع.

ماذا ستتعلم في «functools: ‏partial وreduce»؟

أنشئ دوالاً متخصصة باستخدام partial واطوِ التسلسلات باستخدام reduce تتمرن على Python Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Python Academy؟

لا تُشترط خبرة سابقة. Python Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «functools: ‏partial وreduce»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Python Academy هذا؟

نعم. كل درس في Python Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. itertools: المكرّرات اللانهائية والمحدودة
  2. itertools: التوافقيات
  3. functools: ‏partial وreduce
  4. functools: ‏lru_cache وcached_property
← العودة إلى Python Academy