简体   繁体   English

如何使用python装饰器修复“ NoneType”错误?

[英]How to fix “NoneType” error with python decorators?

I'm doing an LRU (Least Recently Used) cache with decorator to store recently used localization, but when I call function to read it from .json file I get "NoneType" error 我正在使用带有装饰器的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)

I expect that it would return phrase in "en" that stores in .json file, but it says 我希望它会返回存储在.json文件中的“ en”中的词组,但是它说

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

You didn't return the wrapper function form the decorator, hence Python is returning None as usual and trying to call it when you do read_locale(user.locale) . 您没有从装饰器返回包装函数,因此Python照常返回None ,并在您执行read_locale(user.locale)时尝试调用它。 You need: 你需要:

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 ^^^^

You did not return your wrapper at the end of the decorator: 您没有在装饰器的末尾返回 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
    return wrapper

A decorator usually takes as input a function, and returns a function. 装饰器通常将一个函数作为输入,然后返回一个函数。 Here you defined an inner function, but you forgot to return it. 在这里,您定义了一个内部函数,但是您忘了返回它。 As a result, the output of the decorator is None , and you can not make a call to None . 结果,装饰器的输出为None ,并且您无法调用None

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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