在d中使用部分时会丢失

2024-10-02 08:26:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图从一个类中编写一个方法,该类使用另一个类中的装饰器。问题是我需要存储在包含decorator的类中的信息(ClassWithDecorator.decorator参数). 为了达到这个目的,我使用了partial,injecting self作为第一个参数,但是当我这样做的时候,self,来自使用decorator的类的self以某种方式“丢失”了,我最终得到了一个错误。请注意,如果我从my_decorator()中删除partial(),则不会发生这种情况,“self”将正确地存储在*args中。你知道吗

请参见代码示例:

from functools import partial


class ClassWithDecorator:
    def __init__(self):
        self.decorator_param = "PARAM"

    def my_decorator(self, decorated_func):
        def my_callable(ClassWithDecorator_instance, *args, **kwargs):
            # Do something with decorator_param
            print(ClassWithDecorator_instance.decorator_param)
            return decorated_func(*args, **kwargs)

        return partial(my_callable, self)


decorator_instance = ClassWithDecorator()


class WillCallDecorator:
    def __init__(self):
        self.other_param = "WillCallDecorator variable"

    @decorator_instance.my_decorator
    def decorated_method(self):
        pass


WillCallDecorator().decorated_method()

我明白了

PARAM
Traceback (most recent call last):
  File "clinichpo/decorator.py", line 32, in <module>
    WillCallDecorator().decorated_method()
  File "clinichpo/decorator.py", line 12, in my_callable
    return decorated_func(*args, **kwargs)
TypeError: decorated_method() missing 1 required positional argument: 'self'

如何将与WillCallDecorator()相对应的自身传递到decorated_method(),同时将信息从其自己的类传递到my_callable()?你知道吗


Tags: instanceselfparammydefargsdecoratorpartial
2条回答

似乎您可能想使用^{}而不是partial

从文档中:

class functools.partialmethod(func, /, *args, **keywords)

When func is a non-descriptor callable, an appropriate bound method is created dynamically. This behaves like a normal Python function when used as a method: the self argument will be inserted as the first positional argument, even before the args and keywords supplied to the partialmethod constructor.

使用已有的self变量就简单多了。完全没有理由在这里使用partialpartialmethod

from functools import partial


class ClassWithDecorator:
    def __init__(self):
        self.decorator_param = "PARAM"

    def my_decorator(self, decorated_func):
        def my_callable(*args, **kwargs):
            # Do something with decorator_param
            print(self.decorator_param)
            return decorated_func(*args, **kwargs)

        return my_callable


decorator_instance = ClassWithDecorator()


class WillCallDecorator:
    def __init__(self):
        self.other_param = "WillCallDecorator variable"

    @decorator_instance.my_decorator
    def decorated_method(self):
        pass


WillCallDecorator().decorated_method()

另外,为了回答代码为什么不工作的问题,当您访问something.decorated_method()时,代码会检查decorated_method是否是函数,如果是,则在内部将其转换为调用WillCallDecorator.decorated_method(something)。但是从partial返回的值是functools.partial对象,而不是function。所以类查找绑定不会在这里发生。你知道吗

更详细地说,something.method(arg)等价于SomethingClass.method.__get__(something, arg)something没有属性method并且它的类型SomethingClass有属性并且属性有方法__get__时,但是属性查找的全套步骤相当复杂。你知道吗

相关问题 更多 >

    热门问题