2017-08-29 1 views
-2

呼び出される基になるSQLスクリプトがあまりにも騒々しい場合、関数を装飾するためにこのコードを記述しました。 gp_info_decorator(function)は、execute_gp_func()を変更して、SQLスクリプトからのメッセージを抑制します。代わりに、結果はStatus変数に格納されます。Pythonの装飾された関数が正しい値を返すことができない

ただし、装飾された関数は、現在の日付の代わりに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() 

実行時に、関数内のprintが日付に対して正しい値を持つことがわかりました。しかし、ラッパーに入り、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) 
+0

あなたが実際にあなたのデコレータで関数を返すことはありません! –

+0

'psycopg2'をインストールする必要がありますか? [mcve]の作成方法を参照してください。 –

+0

@PeterWoodありがとう、私はそれを念頭に置いておきます。私の質問は、デコレータからの価値を変更することです。したがって、psycopg2は必須ではありません。 – Tammy

答えて

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 
+0

ありがとうございました。私はデコレータを使うのが初めてです。あなたの指導を本当にありがとう。 – Tammy

関連する問題