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

问题描述 投票:0回答:1

在下面的脚本中,我想在调用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
python python-2.x python-decorators
1个回答
0
投票

当定义get_names时,name_typeNone,因为main还没有被调用。这两个if/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,以某种方式对你有意义。

© www.soinside.com 2019 - 2024. All rights reserved.