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

时间:2018-09-07 20:31:30

标签: python python-2.x python-decorators

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

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

1 个答案:

答案 0 :(得分:0)

定义get_names时,name_typeNone,因为尚未调用mainif/elif子句均未运行,因此nameDecorator返回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,这对您来说很有意义。