from functools import singledispatch# Define base function for singledispatch@singledispatchdefprocess(data):print(f"Base function received data of type {type(data).__name__}")# =========================================================# Register function@process.registerdef_(data:str):print(f"Received value '{data}'")# =========================================================# Register function (stacking)@process.register(int)@process.register(float)def_(data):print(f"Received value {data}")# =========================================================# Register function (lambda)process.register(list, lambdax: print(f"Received values {x}"))# =========================================================# Register function (Pre-existing)defprocess_bool(data):print(f"Received with value {data}")# Registering pre-existing functionprocess.register(bool, process_bool)# =========================================================# testingprocess(10)# Output: Received value 10process(10.0)# Output: 10.0process("Hello World")# Output: 'Hello World'process([1, 2, 3])# Output: [1, 2, 3]process(True)# Output: True
範例 – @.register 跨 module
PYTHON
# In module1.pyfrom functools import singledispatch@singledispatchdefprocess(data):print(f"Don't know how to process {data}")@process.register(int)def_(data):print(f"Processing integer: {data}")# =========================================================# In module2.pyfrom module1 import process@process.register(str)def_(data):print(f"Processing string: {data}")process(10)# Outputs: "Processing integer: 10"process("hi")# Outputs: "Processing string: hi"
@singledispatchmethod
它是 @singledispatch 的演變,設計用於實例方法 (Class 方法)。
@<method>.register 第一個參數是實例 (self) 或 Class (cls),第二個參數是考慮調度的參數。
from functools import singledispatchmethodclassNegator():@singledispatchmethod@classmethoddefneg(cls,arg):raiseNotImplementedError("Cannot negate a")@neg.register@classmethoddef_(cls,arg:int):return-arg@neg.register@classmethoddef_(cls,arg:bool):returnnot argprint(Negator.neg(16))print(Negator.neg(True))
PYTHON
import functoolsclassMultiProcessor():@functools.singledispatchmethoddefprocess(self,data):raiseNotImplementedError("Unsupported type")@process.registerdef_(self,data:int):print(f"Processing an integer: {data}")# Do something specific to int@process.registerdef_(self,data:str):print(f"Processing a string: {data}")# Do something specific to str@process.registerdef_(self,data:list):print(f"Processing a list: {data}")# Do something specific to list# Usageprocessor =MultiProcessor()processor.process(42)# Output: Processing an integer: 42processor.process("Hello world")# Output: Processing a string: Hello worldprocessor.process([1, 2, 3])# Output: Processing a list: [1, 2, 3]
PYTHON
import cv2import numpy as npfrom functools import singledispatchmethodclassImageProcessor():@singledispatchmethoddefprocess(self,image):print("Not implemented for this type.")@process.registerdef_(self,image: cv2.VideoCapture):# Processing for video captured from a cameraprint("Processing video capture.")@process.registerdef_(self,image: np.ndarray):# Processing for an image loaded into a NumPy arrayprint("Processing numpy array.")
def reduce(function,iterable,initializer=None): it =iter(iterable)if initializer isNone: value =next(it)else: value = initializerfor element in it: value =function(value, element)return value
範例:
PYTHON
import functoolsdefbitwise_or_operation(a,b):return a | bdata = [1,2,4,8,16,32]result = data[0]# Simple loopfor i inrange(1, len(data)): result =bitwise_or_operation(result, data[i])print(result)# Output: 63# reduce()result = functools.reduce(bitwise_or_operation, data)print(result)# Output: 63# reduce() + lambdaresult = functools.reduce(lambdaa, b: a | b, data)print(result)# Output: 63
PYTHON
import functoolsdefmultiply(x,y):return x * ynumbers = [1,2,3,4,5]product =10# Simple loopfor num in numbers: product =multiply(product, num)print(product)# Output: 1200# reduce()product = functools.reduce(multiply, numbers, 10)print(product)# Output: 1200# reduce() + lambdaproduct = functools.reduce(lambdax, y: x * y, numbers, 10)print(product)# Output: 1200
PYTHON
import cv2import functoolsfrom pathlib import Path# You might need to resize or crop them depending on your use casedefblend_images(image1,image2,alpha=0.5):return cv2.addWeighted(image1, alpha, image2, 1- alpha, 0)file_dir =r".\001"image_files =Path(file_dir).glob("*.png")images = [cv2.imread(str(image))for image in image_files]blended_image = functools.reduce(blend_images, images)cv2.imwrite('output.jpg', blended_image)