Reputation: 133
I have a class decorator that have two arguments as following:
def decoratorB(x: int, y: int):
def inner(cls):
def no_wrap(*args, **kwargs):
return cls(*args, **kwargs)
no_wrap.x = x
no_wrap.y = y
return no_wrap
return inner
and I used it to decorate a class in this way:
@decoratorB(x=100, y=-100)
class ClassB():
def func(self, name):
pass
How can I get the values of x and y from an object of ClassB
?
obj = ClassB()
Thanks in advance.
Upvotes: 3
Views: 120
Reputation: 2007
Try printing the dir of ClassB
vs obj
.
>>> print(dir(obj))
# ['__class__', ..., 'func']
>>> print(dir(ClassB))
# ['__annotations__', ..., 'x', 'y']
Notice how x
and y
are only found in ClassB as a class, not as an instance of it. Also notice how func
is only found in the instance. This is because of how you defined the decorator. We are applying the attributes to no_wrap
instead of the obj itself.
You can either manually set the attributes in __init__
or change the decorator.
@decoratorB(x=100, y=-100)
class ClassB:
def __init__(self):
for attr in dir(ClassB)[35:]: # Get rid of builtin methods so we don't override
setattr(self, attr, getattr(ClassB, attr, None))
def func(self, name):
pass
>>> print(dir(Class())
# ['__class__', ..., 'func', 'x', 'y']
Edit: Thanks to chepner's comment up there, I realized we could just rewrite the decorator instead.
We should take the cls object and assign the values to the object instead of a "copy".
def decoratorB(x: int, y: int):
def inner(cls):
new = cls
new.x = x
new.y = y
return new
return inner
>>> print(dir(ClassB))
# ['__class__', 'func', 'x', 'y']
>>> print(dir(ClassB()))
# ['__class__', 'func', 'x', 'y']
Upvotes: 1