Python 2: Передача глобальной переменной в фабричный декоратор - PullRequest
0 голосов
/ 07 сентября 2018

В приведенном ниже скрипте я хотел бы использовать глобальную переменную 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 голосов
/ 07 сентября 2018

Когда определено get_names, name_type равно None, потому что 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, в некотором смысле, что имеет смысл для вас.

...