如何使用 python 装饰器修复 "NoneType" 错误?
How to fix "NoneType" error with python decorators?
我正在用装饰器做一个 LRU(最近最少使用)缓存来存储最近使用的本地化,但是当我调用函数从 .json 文件中读取它时,我得到 "NoneType" 错误
def loc_cache(func):
loc_cache.locale = {} # {lang:(local, count)} local:dict
loc_cache.MAXLENGTH = 5
def wrapper(key):
print(key) #this function wasn't called
if key not in loc_cache.locale.keys():
try:
locale = read_locale(key)
loc_cache.locale[key] = (locale, 1)
wrapper.locale = locale
except KeyError:
key = "en" # set default locale
wrapper(key)
else:
locale, count = loc_cache.locale[key]
loc_cache.locale[key] = (locale, count+1)
wrapper.locale = locale
return wrapper.locale
@loc_cache
def read_locale(key):
locale = read_json("./config/locale.json", key)
return locale
def auth(user:User):
locale = read_locale(user.locale)
print(locale["auth"])
return
u = User(1) # __init__ takes 1 for id
u.locale = "en"
auth(u)
我希望 return 短语 "en" 存储在 .json 文件中,但它说
Traceback (most recent call last):
File "main.py", line 61, in <module>
auth(u)
File "main.py", line 52, in auth
locale = read_locale(user.locale)
TypeError: 'NoneType' object is not callable
您没有 return 包装函数形成装饰器,因此 Python 像往常一样 returning None
并在您执行 read_locale(user.locale)
。您需要:
def loc_cache(func):
loc_cache.locale = {} # {lang:(local, count)} local:dict
loc_cache.MAXLENGTH = 5
def wrapper(key):
print(key) #this function wasn't called
if key not in loc_cache.locale.keys():
try:
locale = read_locale(key)
loc_cache.locale[key] = (locale, 1)
wrapper.locale = locale
except KeyError:
key = "en" # set default locale
wrapper(key)
else:
locale, count = loc_cache.locale[key]
loc_cache.locale[key] = (locale, count+1)
wrapper.locale = locale
return wrapper.locale
return wrapper
# Here ^^^^
你没有return你的wrapper
装饰器的末尾:
def loc_cache(func):
loc_cache.locale = {} # {lang:(local, count)} local:dict
loc_cache.MAXLENGTH = 5
def wrapper(key):
if key not in loc_cache.locale:
try:
locale = read_locale(key)
loc_cache.locale[key] = (locale, 1)
except KeyError:
key = "en" # set default locale
wrapper(key)
else:
locale, count = loc_cache.locale[key]
loc_cache.locale[key] = (locale, count+1)
wrapper.locale = locale
return wrapper.locale
<b>return wrapper</b>
装饰器通常将一个函数作为输入,returns 是一个函数。在这里你定义了一个内部函数,但是你忘了 return 它。结果,装饰器的输出是 None
,你不能调用 None
.
我正在用装饰器做一个 LRU(最近最少使用)缓存来存储最近使用的本地化,但是当我调用函数从 .json 文件中读取它时,我得到 "NoneType" 错误
def loc_cache(func):
loc_cache.locale = {} # {lang:(local, count)} local:dict
loc_cache.MAXLENGTH = 5
def wrapper(key):
print(key) #this function wasn't called
if key not in loc_cache.locale.keys():
try:
locale = read_locale(key)
loc_cache.locale[key] = (locale, 1)
wrapper.locale = locale
except KeyError:
key = "en" # set default locale
wrapper(key)
else:
locale, count = loc_cache.locale[key]
loc_cache.locale[key] = (locale, count+1)
wrapper.locale = locale
return wrapper.locale
@loc_cache
def read_locale(key):
locale = read_json("./config/locale.json", key)
return locale
def auth(user:User):
locale = read_locale(user.locale)
print(locale["auth"])
return
u = User(1) # __init__ takes 1 for id
u.locale = "en"
auth(u)
我希望 return 短语 "en" 存储在 .json 文件中,但它说
Traceback (most recent call last):
File "main.py", line 61, in <module>
auth(u)
File "main.py", line 52, in auth
locale = read_locale(user.locale)
TypeError: 'NoneType' object is not callable
您没有 return 包装函数形成装饰器,因此 Python 像往常一样 returning None
并在您执行 read_locale(user.locale)
。您需要:
def loc_cache(func):
loc_cache.locale = {} # {lang:(local, count)} local:dict
loc_cache.MAXLENGTH = 5
def wrapper(key):
print(key) #this function wasn't called
if key not in loc_cache.locale.keys():
try:
locale = read_locale(key)
loc_cache.locale[key] = (locale, 1)
wrapper.locale = locale
except KeyError:
key = "en" # set default locale
wrapper(key)
else:
locale, count = loc_cache.locale[key]
loc_cache.locale[key] = (locale, count+1)
wrapper.locale = locale
return wrapper.locale
return wrapper
# Here ^^^^
你没有return你的wrapper
装饰器的末尾:
def loc_cache(func):
loc_cache.locale = {} # {lang:(local, count)} local:dict
loc_cache.MAXLENGTH = 5
def wrapper(key):
if key not in loc_cache.locale:
try:
locale = read_locale(key)
loc_cache.locale[key] = (locale, 1)
except KeyError:
key = "en" # set default locale
wrapper(key)
else:
locale, count = loc_cache.locale[key]
loc_cache.locale[key] = (locale, count+1)
wrapper.locale = locale
return wrapper.locale
<b>return wrapper</b>
装饰器通常将一个函数作为输入,returns 是一个函数。在这里你定义了一个内部函数,但是你忘了 return 它。结果,装饰器的输出是 None
,你不能调用 None
.