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

Functools Module ใน Python: Higher-Order Functions และ Callable Operations

โมดูล functools ให้ utilities สำหรับ Higher-Order Functions - ฟังก์ชันที่รับ/คืนฟังก์ชันอื่น

partial() - Freeze Arguments

สร้างฟังก์ชันใหม่โดยล็อกอาร์กิวเมนต์บางส่วน

>> import functools

# int(x, base=10) → base=2 version
>>> binint = functools.partial(int, base=2)
>>> binint('1001')
9

# User function
>>> def myfunc(a, b):
...     return a * b
>>> part = functools.partial(myfunc, b=10)
>>> part(10)
100

partialmethod() - สำหรับ Method Definition

>> class Cell:
...     def __init__(self):
...         self.alive = False
...     @functools.partialmethod
...     def set_state(self, state, value=True):
...         self.alive = value if state == 'alive' else False
...
>>> c = Cell()
>>> c.set_state('alive')
>>> c.alive
True

cmp_to_key() - แปลง Comparison Function เป็น Key Function

Python 3 ลบ cmp parameter ออกจาก sort() ใช้ key แทน แต่ legacy code ใช้ cmp function

>> from functools import cmp_to_key

>>> class Test:
...     def __init__(self, x):
...         self.x = x
...     def __str__(self):
...         return str(self.x)

>>> def cmp_func(a, b):
...     if a.x >= b.x: return 1
...     return -1

>>> mykey = cmp_to_key(cmp_func)
>>> sorted([Test(3), Test(1), Test(2)], key=mykey)
[, , ]

reduce() - Fold/Accumulate

นำฟังก์ชัน binary ไป apply สะสมทีละตัว (left to right)

>> import functools

>>> def mult(x, y):
...     return x * y

>>> functools.reduce(mult, range(1, 11))
3628800  # 10!

# กับ initial value
>>> functools.reduce(mult, [2, 3, 4], 5)
120  # 5 * 2 * 3 * 4

Decorators อื่นๆ ใน functools

Decoratorใช้สำหรับ
@lru_cacheMemoization (cache ผลลัพธ์)
@total_orderingเติม __lt__, __le__, __gt__, __ge__ จาก __eq__ + หนึ่งใน ordering
@wrapsCopy metadata (__name__, __doc__, etc.) ใน decorator
@singledispatchFunction overloading ตาม type ของ arg แรก

ตัวอย่าง @lru_cache

>> @functools.lru_cache(maxsize=128)
... def fib(n):
...     if n < 2: return n
...     return fib(n-1) + fib(n-2)

>>> fib(100)  # เร็วมากเพราะ cache
354224848179261915075
>>> fib.cache_info()
CacheInfo(hits=98, misses=101, maxsize=128, currsize=101)

@wraps สำคัญสำหรับ Decorators

>> def my_decorator(func):
...     @functools.wraps(func)
...     def wrapper(*args, **kwargs):
...         print("Before")
...         return func(*args, **kwargs)
...     return wrapper

>>> @my_decorator
... def hello():
...     """Say hello"""
...     print("Hello")

>>> hello.__name__
'hello'
>>> hello.__doc__
'Say hello'