Python 2:将全局变量传递给工厂装饰器

Python 2: Passing global variable to factory decorator

在下面的脚本中,我想在调用 get_names 函数时在 decorator 中使用 name_type 全局变量。请不要担心程序逻辑。

name_type=None
def main():
    global name_type
    name_type="FEMALE"
    get_names()

def superNameDecorator(value):
    def nameDecorator(func):
        if value in ["MALE"]:
            def wrapper1(*args,**kwargs):
                original_result=func(*args,**kwargs)
                modified_result= "<MALE>"+original_result + "<\MALE>"
                return modified_result
            return wrapper1
        elif value in ["FEMALE"]:
            def wrapper2(*args,**kwargs):
                original_result=func(*args,**kwargs)
                modified_result= "<FEMALE>"+original_result + "<\FEMALE>"
                return modified_result
            return wrapper2
    return nameDecorator

@superNameDecorator(name_type)
def get_names():
    name='AMY'
    return name

if __name__ == "__main__":
    main()  

当我传递直接字符串 "MALE"/"FEMALE" 时,这工作正常,但在传递 name_type 时抛出以下错误 我在这里错过了什么?

Traceback (most recent call last):
  File "GlobalTesting.py", line 29, in <module>
    main()
  File "GlobalTesting.py", line 5, in main
    get_names()
TypeError: 'NoneType' object is not callable

get_names被定义时,name_typeNone,因为main还没有被调用。 if/elif 子句都没有得到 运行,因此 nameDecorator returns None 绑定到标识符 get_names。一种解决方案是删除 main 并使其成为文件顶部附近的 __name__ 检查。

import os
import re
import sys


name_type=None
if __name == '__main__':  # If this doesn't happen, this error will still occur.
    name_type="FEMALE"

def superNameDecorator(value):
    def nameDecorator(func):
        if value in ["MALE"]:
            def wrapper1(*args,**kwargs):
                original_result=func(*args,**kwargs)
                modified_result= "<MALE>"+original_result + "<\MALE>"
                return modified_result
            return wrapper1
        elif value in ["FEMALE"]:
            def wrapper2(*args,**kwargs):
                original_result=func(*args,**kwargs)
                modified_result= "<FEMALE>"+original_result + "<\FEMALE>"
                return modified_result
            return wrapper2
    return nameDecorator

@superNameDecorator(name_type)
def get_names():
    name='AMY'
    return name

if __name == '__main__':
    get_names()

一个更明智的解决方案是重写您的 nameDecorator 以处理任何 name_type 和缺少 name_type,以某种对您有意义的方式。