简体   繁体   中英

How to use `@dataclass` decorator within a decorator?

I would like to create a class decorator to pre-define some attributes and methods to decorated class. At the same time, I would like that this decorated class be decorated with @dataclass decorator. To make things even easier for the user, I would like the user to have only to use my decorator so that his/her class is decorated with @dataclass .

So here is what I have come up with to decorate a class, so that the decorated class has a new attribute id_ . I am submitting this code to know if the nesting of decoartor is 'acceptable'? Basically, I am not so sure about calling a decorator like a function (while it is a function), so I wonder if there could be side effects?

from dataclasses import dataclass

# My library: complexitiy is allowed.
def indexer(orig_class):
    orig_class = dataclass(orig_class)
    # Copy of original __init__ to call it without recursion.
    orig_init = orig_class.__init__
    id_ = 10

    def __init__(self,*args, **kws):
        self.id_ = id_
        orig_init(self, *args, **kws) # Call the original __init__

    orig_class.__init__ = __init__ # Set the class' __init__ to the new one

    return orig_class

# User environment: importing @indexer decorator: ease of use is targeted.
# Expected behavior is that @indexer provides same functions as @dataclass.
@indexer
class Truc:
    mu : int

# Test
test = Truc(3)

test.mu
Out[37]: 3

test.id_
Out[38]: 10

As a sidenote, I don't know if decorator is better than class inheritance here, when it comes to adding attributes and methods? Thanks for the advices, Bests,

Basically, I am not so sure about calling a decorator like a function (while it is a function), so I wonder if there could be side effects?

decorators in python are syntactic sugar , PEP 318 in Motivation gives following example

def foo(cls):
    pass
foo = synchronized(lock)(foo)
foo = classmethod(foo)

is equivalent to

@classmethod
@synchronized(lock)
def foo(cls):
    pass

In other word decorators allow you to write less lines of codes for getting very same result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM