আমি জানি এই প্রশ্নটি পুরানো, তবে কয়েকটি মন্তব্য নতুন, এবং বাস্তবের সমস্ত সমাধান মূলত একইরকম, বেশিরভাগই খুব পরিষ্কার বা পড়া সহজ নয় to
থোবের উত্তর যেমন বলেছে, উভয় ক্ষেত্রে পরিচালনা করার একমাত্র উপায় হ'ল উভয় পরিস্থিতি পরীক্ষা করা। সবচেয়ে সহজ উপায়টি হল যে কোনও একক যুক্তি আছে কিনা তা যাচাই করা এবং এটি কল্যাব (দ্রষ্টব্য: আপনার ডেকোররেটরটি কেবল 1 টি যুক্তি গ্রহণ করে এবং এটি কলযোগ্য বস্তু হিসাবে ঘটে যদি অতিরিক্ত চেকগুলি প্রয়োজন হয়):
def decorator(*args, **kwargs):
if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
else:
প্রথম ক্ষেত্রে, আপনি কোনও সাধারণ সাজসজ্জাকারী যা করেন তা করেন, ফাংশনটিতে পাসের একটি পরিবর্তিত বা মোড়ানো সংস্করণটি ফিরিয়ে দিন।
দ্বিতীয় ক্ষেত্রে, আপনি একটি 'নতুন' সাজসজ্জা ফিরিয়ে দেন যা কোনওভাবে * আরগস, ** কাওয়ারগুলি দিয়ে দেওয়া তথ্য ব্যবহার করে।
এটি বেশ ভাল এবং সমস্ত, তবে আপনার তৈরি প্রতিটি সজ্জাকারীর জন্য এটি লিখে রাখলে এটি খুব বিরক্তিকর হতে পারে এবং পরিষ্কার হিসাবে নয়। পরিবর্তে, আমাদের সাজসজ্জারগুলিকে পুনরায় না লিখে স্বয়ংক্রিয়ভাবে সংশোধন করতে সক্ষম হবেন ... তবে সাজসজ্জারের জন্য এটিই!
নিম্নলিখিত সাজসজ্জার সজ্জা ব্যবহার করে, আমরা আমাদের সাজসজ্জারকে deocrate করতে পারি যাতে সেগুলি যুক্তি ছাড়াই বা ছাড়াই ব্যবহার করা যায়:
def doublewrap(f):
'''
a decorator decorator, allowing the decorator to be used as:
@decorator(with, arguments, and=kwargs)
or
@decorator
'''
@wraps(f)
def new_dec(*args, **kwargs):
if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
return f(args[0])
else:
return lambda realf: f(realf, *args, **kwargs)
return new_dec
এখন, আমরা @ ডাবলাপ্র্যাপ দিয়ে আমাদের সাজসজ্জাগুলি সাজাতে পারি, এবং তারা একটি সতর্কতার সাথে যুক্তি ছাড়াই এবং ছাড়াই কাজ করবে:
আমি উপরে উল্লেখ করেছি তবে এখানে পুনরাবৃত্তি করা উচিত, এই ডেকোরেটরটিতে থাকা চেকটি একটি সজ্জাকার গ্রহণ করতে পারে এমন আর্গুমেন্ট সম্পর্কে ধারণা তৈরি করে (যথা এটি একটি একক, কলযোগ্য আর্গুমেন্ট গ্রহণ করতে পারে না)। যেহেতু আমরা এখন এটি যেকোন জেনারেটরের জন্য প্রযোজ্য করে তুলছি, তাই এটি বিবেচনায় রাখা দরকার বা এটি বিপরীত হলে সংশোধন করা দরকার।
নিম্নলিখিতগুলি এর ব্যবহারটি দেখায়:
def test_doublewrap():
from util import doublewrap
from functools import wraps
@doublewrap
def mult(f, factor=2):
'''multiply a function's return value'''
@wraps(f)
def wrap(*args, **kwargs):
return factor*f(*args,**kwargs)
return wrap
@mult
def f(x, y):
return x + y
@mult(3)
def f2(x, y):
return x*y
@mult(factor=5)
def f3(x, y):
return x - y
assert f(2,3) == 10
assert f2(2,5) == 30
assert f3(8,1) == 5*7
@redirect_outputচেহারাটি লক্ষণীয়ভাবে অযৌক্তিক। আমি পরামর্শ দিচ্ছি যে এটি একটি খারাপ ধারণা। প্রথম ফর্মটি ব্যবহার করুন এবং আপনার জীবনকে অনেক সহজ করুন।