簡體   English   中英

Python從裝飾器返回額外的值

[英]Python return extra value from decorator

我有一些函數,我想根據裝飾器中傳遞給它的參數值進行一些計算。 我能夠實現這一點,但裝飾器會填充一個重要的對象,稍后我將重用該對象。 例如..

def my_awesome_decorator(*d):
    how_do_i_return_this_object_which_got_created_here
    def wrapping_function(func):
        def wrapper(*args, **kwargs):
            ...
        return wrapper
    return wrapping_function


class A:
    @my_awesome_decorator(d)
    def fun(a, b, c):
        ...

我希望使用object_A.how_do_i_return_this_object_which_got_created_here可以輕松訪問該對象

這不是裝飾員可以做的。 裝飾者所能做的就是為給定的函數對象返回不同的東西。 在命名空間中,您無法選擇將返回值分配給什么。

更好的選擇是:

  • 在修飾函數上使用屬性:

     def my_awesome_decorator(*d): def wrapping_function(func): def wrapper(*args, **kwargs): # ... wrapper.some_attribute = ... return wrapper return wrapping_function 

    之后可以使用ClassObject.methodname.some_attributeinstance.methodname.some_attribute

  • 對於Python 3.6或更高版本,可以為類的基類添加__init_subclass__方法。 它可以與裝飾器設置的屬性結合使用,以將屬性復制到類中:

     class BaseClass: def __init_subclass__(cls, **kwargs): super().__init_subclass__() special = None for attr in vars(cls).values(): special = getattr(attr, '_special_attribute_name', None) if special is not None: break cls.target_attribute = special 

    之后,子類將跨找到的第一個method._special_attribute_name屬性復制到類對象; 裝飾者可以在方法上設置該屬性。

  • 對於早期的Python版本,請使用元類執行相同的操作:

     class SomeMetaClass(type): def __new__(mcls, name, bases, namespace, **kwds): special = None for attr in namespace.values(): special = getattr(attr, '_special_attribute_name', None) if special is not None: break namespace['target_attribute'] = special return super().__new__(mcls, name, bases, namespace, **kwds) 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM