আমি সম্মত হই যে উত্তোলিত সমস্যার জন্য উত্তরাধিকার উত্তম ফিট।
আমি এই প্রশ্নটি সার্থকভাবে দেখতে পেলাম যদিও সাজসজ্জা শ্রেণিতে, সমস্ত ধন্যবাদ।
পাইথন ২.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_if
decorator
যদি কেবল condition
মূল্যায়ন করে তবেই প্রযোজ্য True
।
getattr
, callable
পরীক্ষা এবং @decorate_if
তাই ব্যবহার করা হয় যে প্রসাধক যদি ভাঙে না foo()
পদ্ধতি বর্গ সজ্জিত হচ্ছে অস্তিত্ব নেই।