【发布时间】:2022-01-21 13:35:38
【问题描述】:
我在 python 中有一个类,其结构如下:
class MyClass:
def __init__(self, iterable):
self.iterable = iterable
def example_0(self):
for i in self.iterable:
print(i)
def example_1(self):
for i in self.iterable:
print(i + 1)
def example_2(self):
for i in self.iterable:
print(i + 2)
也就是说,我有几个方法可以在作为类属性的可迭代对象上运行不同的操作。我需要为类中的每个方法运行for i in self.iterable,否则我想对所有这些方法使用装饰器,例如:
class MyClass:
def __init__(self, iterable):
self.iterable = iterable
@iterate
def example_0(self, i):
print(i)
@iterate
def example_1(self, i):
print(i + 1)
@iterate
def example_2(self, i):
print(i + 2)
你能帮我编写这个装饰器,使我的类的行为与新类的行为相同吗?
我试过了:
class MyClass:
def __init__(self, iterable):
self.iterable = iterable
def iterate(self, f):
def func(*args, **kwargs):
for i in self.iterable:
f(self, i, *args, **kwargs)
return func
@iterate
def example_0(self, i):
print(i)
@iterate
def example_1(self, i):
print(i + 1)
@iterate
def example_2(self, i):
print(i + 2)
它返回:TypeError: iterate() missing 1 required positional argument: 'f'。
我的主要问题是我不确定如何将装饰器放在我的类中,因为它正在迭代类的属性。
【问题讨论】:
-
你知道一般怎么写装饰器吗?如果是这样,您是否尝试编写此装饰器?你的尝试出了什么问题?如果你被卡住了,特别是为什么你被卡住了(如你所见)?一般不能"help you";我们需要一个明确的问题。
-
这样的装饰器看起来与您现在拥有的方法非常相似。你到底在为什么呢?你知道如何编写这样一个 不 迭代某些东西的装饰器吗?
-
我可以建议完全不同的方法吗?编写 one 方法,该方法接受一个函数作为参数,迭代可迭代对象并将函数应用于每个;然后你可以传入例如
print、lambda i: print(i + 1)等 -
我认为装饰器不应该在它的初始化中使用
self,而是在 func 中。装饰器本身不是类方法。 -
“我的主要问题是我不确定如何将装饰器放在我的类中,因为它正在迭代类的属性。”不需要,因为
self将像传递到原始版本一样传递到装饰版本。把它放在里面会导致问题,因为当你尝试应用装饰器时,Python 想要调用iterate作为方法,但是没有实例可以提前使用 .您可以通过装饰装饰器(使用@staticmethod)并删除self参数来解决此问题;但实际上把它放在外面更容易。