এটি সুপরিচিত যে নিম্নলিখিত দুটি টুকরো কোড প্রায় সমতুল্য:
@dec
def foo():
pass foo = dec(foo)
############################################
foo = dec(foo)
একটি সাধারণ ভুল হ'ল ভাবনা যা @
কেবল বামতম যুক্তিটি গোপন করে।
@dec(1, 2, 3)
def foo():
pass
###########################################
foo = dec(foo, 1, 2, 3)
উপরেরটি যদি @
কাজ করে তবে এটি সজ্জা লেখার কাজটি অনেক সহজ হবে । দুর্ভাগ্যক্রমে, জিনিসগুলি এভাবে করা হয় না।
কোনও সজ্জাকারীর কথা বিবেচনা করুন Wait
যা কয়েক সেকেন্ডের জন্য প্রোগ্রামের প্রয়োগ কার্যকর করে। আপনি যদি অপেক্ষা অপেক্ষা না করে থাকেন তবে ডিফল্ট মানটি 1 সেকেন্ড। ব্যবহারের কেসগুলি নীচে দেখানো হয়েছে।
##################################################
@Wait
def print_something(something):
print(something)
##################################################
@Wait(3)
def print_something_else(something_else):
print(something_else)
##################################################
@Wait(delay=3)
def print_something_else(something_else):
print(something_else)
যখন Wait
কোনও যুক্তি থাকে যেমন যেমন @Wait(3)
, তখন অন্য কিছু হওয়ার আগেই কলটি Wait(3)
কার্যকর করা হয়।
তা হল, নিম্নলিখিত দুটি টুকরো কোড সমান
@Wait(3)
def print_something_else(something_else):
print(something_else)
###############################################
return_value = Wait(3)
@return_value
def print_something_else(something_else):
print(something_else)
এটা একটা সমস্যা.
if `Wait` has no arguments:
`Wait` is the decorator.
else: # `Wait` receives arguments
`Wait` is not the decorator itself.
Instead, `Wait` ***returns*** the decorator
একটি সমাধান নীচে দেখানো হয়েছে:
আসুন নীচের ক্লাসটি তৈরি করে শুরু করুন DelayedDecorator
:
class DelayedDecorator:
def __init__(i, cls, *args, **kwargs):
print("Delayed Decorator __init__", cls, args, kwargs)
i._cls = cls
i._args = args
i._kwargs = kwargs
def __call__(i, func):
print("Delayed Decorator __call__", func)
if not (callable(func)):
import io
with io.StringIO() as ss:
print(
"If only one input, input must be callable",
"Instead, received:",
repr(func),
sep="\n",
file=ss
)
msg = ss.getvalue()
raise TypeError(msg)
return i._cls(func, *i._args, **i._kwargs)
এখন আমরা এই জাতীয় জিনিস লিখতে পারি:
dec = DelayedDecorator(Wait, delay=4)
@dec
def delayed_print(something):
print(something)
মনে রাখবেন যে:
dec
একাধিক যুক্তি গ্রহণ করে না।
dec
কেবল মোড়ানোর জন্য ফাংশনটি গ্রহণ করে।
PolyArgDecoratorMeta (প্রকার) শ্রেণি আমদানি করুন: ডিএফ কল (অপেক্ষা করুন, * আরগস, ** কোয়ার্গস): চেষ্টা করুন: আরগ_কাউন্ট = লেন (আরগস) যদি (আরগ_কাউন্ট == 1): কলযোগ্য (আরগস [0]): সুপারক্লাস = পরিদর্শন করুন। getmro (PolyArgDecoratorMeta) [1] r = সুপারক্লাস। কল করুন (অপেক্ষা করুন, আরগস [0]) অন্য: r = বিলম্বিত ডেকোরেটর (অপেক্ষা করুন, * আরগস, ** কোয়ার্গস) অন্য: আর = বিলম্বিত ডেকোরেটর (অপেক্ষা করুন, * আরগস, ** কাওয়ার্গস) অবশেষে: পাস রিটার্ন
আমদানির সময় শ্রেণি অপেক্ষা (metaclass = PolyArgDecoratorMeta): Def init (i, func, বিলম্ব = 2): i._func = func i._delay = বিলম্ব
def __call__(i, *args, **kwargs):
time.sleep(i._delay)
r = i._func(*args, **kwargs)
return r
নিম্নলিখিত দুটি টুকরো কোড সমান:
@Wait
def print_something(something):
print (something)
##################################################
def print_something(something):
print(something)
print_something = Wait(print_something)
আমরা "something"
কনসোলে খুব ধীরে ধীরে মুদ্রণ করতে পারি , নীচে:
print_something("something")
#################################################
@Wait(delay=1)
def print_something_else(something_else):
print(something_else)
##################################################
def print_something_else(something_else):
print(something_else)
dd = DelayedDecorator(Wait, delay=1)
print_something_else = dd(print_something_else)
##################################################
print_something_else("something")
চূড়ান্ত নোটস
এটি অনেকটা কোডের মতো দেখতে পারে তবে আপনাকে ক্লাস DelayedDecorator
এবং PolyArgDecoratorMeta
প্রতিবার লিখতে হবে না । আপনাকে ব্যক্তিগতভাবে নিম্নরূপ কিছু লিখতে হবে এমন কোডটি যা মোটামুটি সংক্ষিপ্ত:
from PolyArgDecoratorMeta import PolyArgDecoratorMeta
import time
class Wait(metaclass=PolyArgDecoratorMeta):
def __init__(i, func, delay = 2):
i._func = func
i._delay = delay
def __call__(i, *args, **kwargs):
time.sleep(i._delay)
r = i._func(*args, **kwargs)
return r
execute_complete_reservation
দুটি প্যারামিটার লাগে তবে আপনি এটি পাস করছেন। সাজসজ্জারগুলি অন্যান্য ফাংশনের অভ্যন্তরে ফাংশন মোড়ানোর জন্য কেবল সিনট্যাকটিক চিনি। সম্পূর্ণ ডকুমেন্টেশনের জন্য docs.python.org/references/compound_stmts.html# ফাংশন দেখুন ।