#python #python-decorators
Вопрос:
У меня есть следующий фрагмент кода, в котором есть два метода func_norule() и func_with_rule(). Метод func_with_rule() украшен @rule, где в качестве функции func_norule() нет никакого декоратора.
Когда я использую функцию getattr, fn = getattr(self, ‘func_norule’) возвращает функцию, где как fn = getattr(self, ‘func_with_rule’) не возвращает ничего.
Есть ли причина, по которой поведение при использовании декоратора отличается от того, когда декоратор не используется? Есть какие-нибудь способы решения этой проблемы?
class Student():
def __init__(self, name, roll_no):
self.name = name
self.roll_no = roll_no
## Decorator function to decorate all the rules function
def rule(func):
print(func.__name__)
def func_norule(self):
#This method works with getattr
print("func_norule:" self.name)
@rule
def func_with_rule(self):
#This method returns None with getattr
print("func_with_rule:" self.name)
def myFunc2(self):
fn = getattr(self, 'func_norule')
fn()
fn = getattr(self, 'func_with_rule')
fn()
student = Student('myName', 8)
student.myFunc2()
Комментарии:
1. Это совсем не то, как должен работать декоратор. Он должен возвращать функцию (новую, украшенную функцию), которая заменит не украшенную. Ваш просто ничего не возвращает явно, поэтому он возвращается
None
.
Ответ №1:
Это потому, что вы не привязываетесь self
к своему декоратору. Вы можете изменить свой декоратор, чтобы self
параметр был передан вашему методу оформления:
class Student:
# ...
def rule(func):
def _(self, *args, **kwargs):
print("Before calling", func.__name__)
result = func(self, *args, **kwargs)
print("After calling", func.__name__)
return result
return _
# ...
@rule
def func_with_rule(self):
#This method returns None with getattr
print("func_with_rule:" self.name)
Теперь, когда вы это сделаете
student = Student('myName', 8)
student.myFunc2()
выходы
func_norule:myName
Before calling func_with_rule
func_with_rule:myName
After calling func_with_rule
Комментарии:
1. Спасибо @enzo, это решение сработало для меня!