আমি সম্মত হই যে উত্তোলিত সমস্যার জন্য উত্তরাধিকার উত্তম ফিট।
আমি এই প্রশ্নটি সার্থকভাবে দেখতে পেলাম যদিও সাজসজ্জা শ্রেণিতে, সমস্ত ধন্যবাদ।
পাইথন ২.7-এ উত্তরাধিকার কীভাবে জিনিসগুলিকে প্রভাবিত করে (এবং @ র্যাপস , যা মূল ফাংশনের ডক্ট্রিং ইত্যাদি রক্ষা করে) সহ অন্যান্য উত্তরের উপর ভিত্তি করে এখানে আরও কয়েকটি উদাহরণ রয়েছে :
def dec(klass):
old_foo = klass.foo
@wraps(klass.foo)
def decorated_foo(self, *args ,**kwargs):
print('@decorator pre %s' % msg)
old_foo(self, *args, **kwargs)
print('@decorator post %s' % msg)
klass.foo = decorated_foo
return klass
@dec # No parentheses
class Foo...
প্রায়শই আপনি আপনার ডেকরেটারে প্যারামিটার যুক্ত করতে চান:
from functools import wraps
def dec(msg='default'):
def decorator(klass):
old_foo = klass.foo
@wraps(klass.foo)
def decorated_foo(self, *args ,**kwargs):
print('@decorator pre %s' % msg)
old_foo(self, *args, **kwargs)
print('@decorator post %s' % msg)
klass.foo = decorated_foo
return klass
return decorator
@dec('foo decorator') # You must add parentheses now, even if they're empty
class Foo(object):
def foo(self, *args, **kwargs):
print('foo.foo()')
@dec('subfoo decorator')
class SubFoo(Foo):
def foo(self, *args, **kwargs):
print('subfoo.foo() pre')
super(SubFoo, self).foo(*args, **kwargs)
print('subfoo.foo() post')
@dec('subsubfoo decorator')
class SubSubFoo(SubFoo):
def foo(self, *args, **kwargs):
print('subsubfoo.foo() pre')
super(SubSubFoo, self).foo(*args, **kwargs)
print('subsubfoo.foo() post')
SubSubFoo().foo()
আউটপুট:
@decorator pre subsubfoo decorator
subsubfoo.foo() pre
@decorator pre subfoo decorator
subfoo.foo() pre
@decorator pre foo decorator
foo.foo()
@decorator post foo decorator
subfoo.foo() post
@decorator post subfoo decorator
subsubfoo.foo() post
@decorator post subsubfoo decorator
আমি আরও একটি সংক্ষিপ্ত দেখতে আমি একটি ফাংশন সজ্জা ব্যবহার করেছি। শ্রেণি সাজানোর জন্য এখানে একটি ক্লাস রয়েছে:
class Dec(object):
def __init__(self, msg):
self.msg = msg
def __call__(self, klass):
old_foo = klass.foo
msg = self.msg
def decorated_foo(self, *args, **kwargs):
print('@decorator pre %s' % msg)
old_foo(self, *args, **kwargs)
print('@decorator post %s' % msg)
klass.foo = decorated_foo
return klass
আরও শক্তিশালী সংস্করণ যা এই বন্ধনীগুলির জন্য যাচাই করে এবং যদি পদ্ধতিগুলি সজ্জিত শ্রেণিতে উপস্থিত না থাকে তবে তা কাজ করে:
from inspect import isclass
def decorate_if(condition, decorator):
return decorator if condition else lambda x: x
def dec(msg):
# Only use if your decorator's first parameter is never a class
assert not isclass(msg)
def decorator(klass):
old_foo = getattr(klass, 'foo', None)
@decorate_if(old_foo, wraps(klass.foo))
def decorated_foo(self, *args ,**kwargs):
print('@decorator pre %s' % msg)
if callable(old_foo):
old_foo(self, *args, **kwargs)
print('@decorator post %s' % msg)
klass.foo = decorated_foo
return klass
return decorator
assertচেক যে প্রসাধক প্রথম বন্ধনী ছাড়া ব্যবহার করা হয়েছে। যদি এটি থাকে, তবে সাজানো শ্রেণিটি সাজসজ্জারের msgপ্যারামিটারে দেওয়া হবে, যা একটি উত্থাপন করে AssertionError।
@decorate_ifdecoratorযদি কেবল conditionমূল্যায়ন করে তবেই প্রযোজ্য True।
getattr, callableপরীক্ষা এবং @decorate_ifতাই ব্যবহার করা হয় যে প্রসাধক যদি ভাঙে না foo()পদ্ধতি বর্গ সজ্জিত হচ্ছে অস্তিত্ব নেই।