Python 3.x 将装饰器应用于派生子类的所有方法
我有一个非常通用的特定类,我想派生另一个类,其中a命令在类方法之前运行 我选择的路径是基于。我尝试了许多其他的方法,但我觉得我理解它是如何工作的。嗯,我也错了。 我的理解是,过程如下:1)创建一个子类,2)获取基类的所有可调用方法,3)用修饰过的版本覆盖这些方法 我的代码是:Python 3.x 将装饰器应用于派生子类的所有方法,python-3.x,decorator,subclass,Python 3.x,Decorator,Subclass,我有一个非常通用的特定类,我想派生另一个类,其中a命令在类方法之前运行 我选择的路径是基于。我尝试了许多其他的方法,但我觉得我理解它是如何工作的。嗯,我也错了。 我的理解是,过程如下:1)创建一个子类,2)获取基类的所有可调用方法,3)用修饰过的版本覆盖这些方法 我的代码是: from functools import wraps, partial def deco_func(func): #, channel): @wraps(func) def new_func
from functools import wraps, partial
def deco_func(func): #, channel):
@wraps(func)
def new_function(*args,**kwargs):
print("Decorator func.")
return func(*args,**kwargs)
return new_function
print("checking the operation of the decorator function")
def sq(a):
print(a**2)
sq2 = deco_func(sq)
sq(1.1)
sq2(1.3) # yep, sq2 works
class my_class():
def __init__(self, a):
self.a = a
def square(self):
self.a = self.a**2
print(self.a)
class my_subclass(my_class):
def __init__(self, func, *args, **kwargs):
super().__init__(*args, **kwargs)
# go over all elements in my_class and if it is callable, apply the
# decorator function
for attr_name in my_class.__dict__:
attr = getattr(self, attr_name)
if callable(attr) and a:
print("Callable method found: %r" % attr_name)
setattr(self, attr_name, partial(func, attr))
class my_subclass2(my_class):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# go over all elements in my_class and if it is callable, apply the
# decorator function
for attr_name in my_class.__dict__:
attr = getattr(self, attr_name)
if callable(attr) and a:
print("Callable method found: %r" % attr_name)
setattr(self, attr_name, partial(deco_func, attr))
print("\nOriginal class:")
a = my_class(1.05)
a.square()
a.square()
print("Supposed to be 1.05^4: %r" % a.a)
print("\nFirst subclass version:")
b = my_subclass(a=1.07, func=deco_func)
b.square()
b.square()
print("Supposed to be 1.07^4: %r" % b.a)
print("\nSecond subclass version:")
c = my_subclass2(a=1.03)
c.square()
c.square()
print("Supposed to be 1.03^4: %r" % c.a)
输出为:
checking the operation of the decorator function
1.2100000000000002
Decorator func.
1.6900000000000002
Original class:
1.1025
1.21550625
Supposed to be 1.05^4: 1.21550625
First subclass version:
Callable method found: '__init__'
Callable method found: 'square'
Supposed to be 1.07^4: 1.07
Second subclass version:
Callable method found: '__init__'
Callable method found: 'square'
Supposed to be 1.03^4: 1.03
问题是b.square()
和c.square()
返回函数对象,但我不明白为什么。我希望c.square()与deco_func(my_class.square())相同,后者是sq2()。显而易见的问题是我错在哪里,为什么修饰类函数返回另一个函数,以及我如何克服这个问题
我使用python 3.6.9。函数partial()以某种方式破坏了代码。下面是一个MWE,它可以工作。不幸的是,我不能给装饰师添加一个论点,但我现在可以接受
from functools import wraps, partial
import inspect, types
def deco_func(func):
@wraps(func)
def new_function(*args,**kwargs):
print("Decorator func.")
return func(*args,**kwargs)
return new_function
class my_class():
def __init__(self, a):
self.a = a
def square(self):
self.a = self.a**2
print(self.a)
class my_subclass(my_class):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for attr_name in my_class.__dict__:
attr = getattr(self, attr_name)
if callable(attr) and attr_name[0:2] != "__":
print("Callable method found: %r" % attr_name)
setattr(self, attr_name, deco_func(attr))
print("\nOriginal class:")
a = my_class(1.02)
a.square()
a.square()
print("Supposed to be 1.02^4=1.082: %r" % a.a)
print("\nSubclass version:")
b = my_subclass(a=1.01)
b.square()
b.square()
print("Supposed to be 1.01^4=1.04: %r" % b.a)
而不是让孩子实现parents方法。让孩子实现父母使用的方法。因此,让父级实现使用
\u square
的square()
,让子级实现\u square
方法。。。。