Почему декоратор изменяет тип функции на NoneType
Пытался создать игру в палочки, но столкнулся с такой проблемой, что при применении декоратора функция становится объектом типа NoneType
Вот код:
from functools import wraps
CountOfSticks = int(input("Введите начальное кол-во палочек: "))
name1 = str(input("Введите имя первого игрока: "))
name2 = str(input("Введите имя второго игрока: "))
def funcdeco(func):
@wraps(func)
def wrapper(*args, **kwargs):
for n in args:
if n == name1:
print(f"Выбирает игрок {name1}")
result = func(*args, **kwargs)
print(f"Игрок {name1} выбрал {result}")
return print("Выбирает следующий игрок!\n")
for i in args:
if i == name2:
print(f"Выбирает игрок {name2}")
result = func(*args, **kwargs)
print(f"Игрок {name2} выбрал {result}")
return print("Выбирает следующий игрок!\n")
return wrapper()
@funcdeco
def tyanite(name):
vibor = int(input(f"{name} введите кол-во палочек, которые хотите вытянуть: "))
global CountOfSticks
CountOfSticks=CountOfSticks-vibor
return CountOfSticks
print(type(tyanite))
while CountOfSticks:
tyanite(name1)
print(f"Осталось {CountOfSticks} палочек")
if CountOfSticks == 0:
print(f"Выйграл игрок {name1}")
break
tyanite(name2)
print(f"Осталось {CountOfSticks} палочек")
if CountOfSticks == 0:
print(f"Выйграл игрок {name2}")
break
print(type(tyanite)) прописал, чтобы проверить сам тип, собственно
Я здесь новенький, поэтому если я не правильно оформил вопрос, то напишите об этом, пожалуйста
Ответы (1 шт):
def funcdeco(func):
@wraps(func)
def wrapper(*args, **kwargs):
...
return wrapper()
^^ <- ЭТО ВЫЗОВ ФУНКЦИИ wrapper!
В декораторе возвращать нужно не вызов внутренней функции, а ссылку на неё:
def funcdeco(func):
@wraps(func)
def wrapper(*args, **kwargs):
...
return wrapper # <- возвращаем ссылку на функцию, так правильно
Из-за скобок у вас из декоратора возвращается то, что возвращает wrapper при вызове, а он у вас не возвращает ничего. В общем-то это довольно типичная ошибка в питоне - возврат результата вызова функции там, где нужно вернуть ссылку на саму функцию. С точки зрения языка обе конструкции вполне легальны, вызов функции вполне может возвращать ссылку на какую-то функцию, поэтому сам питон не видит тут никакой ошибки.