I am trying to decorate my instance car_details with another instance method decor but am not able to figure out why this is giving the error. while i call the call car_details method like below
if __name__ == '__main__':
car_type = input("Enter type of car: ")
price = int(input("Enter price of car: "))
obj = Car(car_type, price)
decor = obj.decor
details = obj.car_details
tax = {1: "Yes", 2: "No"}
to_apply = int(input("Select 1 for applying tax and 0 for No:"))
ans = tax.get(to_apply)
res = decor(details)
res(ans)
then it works properly, but while i try it with the @decorator at that time i get issue.
TypeError: decor() missing 1 required positional argument: 'func'
TYPE = {'hybrid': 'Hybrid', 'petrol': 'Petrol', 'deasel': 'Deasel'}
def tax_price(car_type):
if car_type == 'hybrid':
SGST = 300000
GST = 500000
elif car_type == 'petrol':
SGST = 200000
GST = 400000
elif car_type == 'deasel':
SGST = 100000
GST = 300000
return SGST+GST
class Car:
def __init__(self, car_type, price):
self.car_type = car_type
self.price = price
def decor(self, func):
def wrapper(apply_tax):
if apply_tax == 'Yes':
car_tax = tax_price(self.car_type)
self.price += car_tax
func()
else:
func()
return wrapper
@decor
def car_details(self):
print("Car Type:", self.car_type)
print("Car Price: ", self.price)
if __name__ == '__main__':
car_type = input("Enter type of car: ")
price = int(input("Enter price of car: "))
obj = Car(car_type, price)
tax = {1: "Yes", 2: "No"}
to_apply = int(input("Select 1 for applying tax and 0 for No:"))
ans = tax.get(to_apply)
wrp = obj.car_details()
wrp(ans)
I see a few problems here. The biggest problem is you seem to be trying to use a decorator when a decorator is really (and I mean really) not suitable for this situation. If this code is not experimental and is to be maintained by someone, I strong suggest simplifying to:
But if you are just experimenting and want to make it work with decorators, I see the following problems:
When a decorator is called, the only arg passed to it is the function being decorated, not
selfwhich is not passed in at all. That meansdef decor(self, func):will need to change todef decor(func):.When the decorated function, which is a method of a class, is invoked, the first arg will be
self. That meansdef wrapper(apply_tax):will need to change todef wrapper(self, apply_tax):.When the wrapped functions is invoked, it needs
selfas its only arg. That meansfunc()will need to change tofunc(self)(in both places).So, that gives:
But, how does the decorated function get a value for
apply_tax? It needs to be passed as an arg. So, you'll need ...Since this is a call on an instance, Python will automatically add
selfas the first arg and sincecar_detailsis decorated it will effectively be callingwrapper(self, ans).