Python修饰函数无法返回正确的值

时间:2017-08-29 15:03:10

标签: python decorator python-decorators

如果被调用的底层sql脚本太嘈杂,我已编写此代码来修饰函数。 gp_info_decorator(function)修改execute_gp_func()以禁止来自sql脚本的消息。相反,它只是将结果存储在Status变量中。

但是,装饰函数返回None,而不是当前日期。

import sys
import psycopg2
import json
import os
#import contextlib.contextmanager
import sys

#  functions to train and predict
class GetExecutor:

    #global props
    # create instance variables from the properties file

    def __init__(self,home_dir, os_type = "linux"):
        if sys.platform in ('linux', 'linux2'):
            self.home_dir = home_dir
            self.os_type = 'linux'
            self.dbname = None
            self.user = None
            self.host = None
            self.passwd = None
            self.conn = None

        elif sys.platform in ('win32'):
            self.home_dir = home_dir
            self.os_type = 'windows'
            self.dbname = None
            self.user = None
            self.host = None
            self.passwd = None
            self.conn = None

    def read_properties(self):
        with open('properties.json', 'r') as f1:
            props = json.load(f1)
            self.dbname = props['dbname']
            self.user = props['user']
            self.host = props['host']
            self.passwd = props['passwd']
            #self.start_date = props['start_date']
            #self.end_date = props['end_date']
        print ("Properties stored")
        return props

    # sql connector
    def sql_connect(self):
        try:
            connect_string = "dbname = %s user = %s host = %s password = %s"%(self.dbname, self.user, self.host, self.passwd)
            conn = psycopg2.connect(connect_string)
            conn.set_isolation_level(0)
            print ("Connecting --")
        except:
            print "Unable to connect to the database"
        self.conn = conn

    # suppress logger info from sql if it is too much noise during execution
    def gp_info_decorator(function):
        def wrapper(*args, **kwargs):
            #print args[0].home_dir
            #print args[0].query
            #with open(sys.stdout, "w") as devnull:
            function(*args, **kwargs)
            """
            with open(os.devnull, "w") as devnull:
                old_stdout = sys.stdout
                sys.stdout = devnull
                try:
                    function(*args, **kwargs)
                finally:
                    sys.stdout = old_stdout
            """
            print ("Debug 3--->", wrapper)
        return wrapper

    # Execute training
    @gp_info_decorator
    def execute_gp_func(self, home_dir, query):
        print ("Function Name:", query)
        with self.conn.cursor() as cursor:
            cursor.execute(query)
            print "Executing-->"
            Status= cursor.fetchall()
            print ("Status is ", Status)
        for notice in self.conn.notices:
            print notice
        print ("Debug 2--->", Status)
            #Status = 
        return Status    

def main():
    home_dir = os.getcwd()
    print home_dir
    obj = GetExecutor(home_dir)
    print obj
    props = obj.read_properties()
    obj.sql_connect()

    #status = obj.execute_gp_func(home_dir,"select get_analytic.fn_get_logistics_train_data(%s,%s);"%(props['start_date'],props['end_date']))
    status = obj.execute_gp_func(home_dir,"select current_date")
    print ("Status of load cost training:" , status)

    # Bill process date date params
    #status = obj.execute_gp_func(home_dir,"select get_analytic.fn_get_logistics_bill_date_train(%s,%s);"%(props['start_date'],props['end_date']))
    print ("Status of bill process date training:" , status)

if __name__ == '__main__':
    main()

执行时,我看到函数内的打印具有正确的日期值。但是,它进入包装器然后返回None值。

<__main__.GetExecutor instance at 0x000000000AE8DE48>
Properties stored
Connecting --
('Function Name:', 'select current_date')
Executing-->
('Status is ', [(datetime.date(2017, 8, 29),)])
('Debug 2--->', [(datetime.date(2017, 8, 29),)])
('Debug 3--->', <function wrapper at 0x000000000AE56AC8>)
('Status of load cost training:', None)
('Status of bill process date training:', None)

1 个答案:

答案 0 :(得分:3)

看起来您的包装器只调用该函数,但对返回值没有任何作用:

def gp_info_decorator(function):
    def wrapper(*args, **kwargs):
        #print args[0].home_dir
        #print args[0].query
        #with open(sys.stdout, "w") as devnull:
        result = function(*args, **kwargs) # <-- remember result
        """
        ... # <-- removed for readability
        """
        print ("Debug 3--->", wrapper)
        return result # <-- return result
    return wrapper

@gp_info_decorator
def fn1():
    return 5

r = fn1()
print(r) # Output: 5