zoukankan      html  css  js  c++  java
  • 一个装饰器的例子

    需求是:用文件的方式模拟select,insert 等操作
    因为是模拟,不用数据库模块实现
    用文件模拟数据库,记录形式是 id,name,dept,phoe,eroll_data记录到磁盘
    支持select ,insert 等标准形式的sql语法
    用了两个 模块实现需求
    sql_func.py 用来执行sql操作
    mock_sql.py用来解析用户的输入
    其中,在mock_sql.py里面用了装饰器parse_user_input用来解析用户的输入,通过这个装饰器,得到用户不同的sql语句对应的表名,字段名,和限定条件(比如where 子句后面的条件),和insert 操作里的values的内容
    用了反射的方法去匹配不同的insert/delete/update/select的具体函数
    具体到sql_func.py里面实现的都是字符串解析,通过字符串解析获取内容,写入文件
    sql_func里面的 read_file()函数实现读取文件,对应select功能
    sql_func里面的get_last_line实现读取当前文件的最后一行的功能,这个是为了给insert用的 ,inser实现id自增,需要判断当前最后一行的id号
    sql_func里面的write_file()函数实现写文件
    文件名: sql_func.py

    # coding:utf-8
    
    import re
    import os
    
    def insert(action_name, dbname, fieldname, condition_limit, condition_values):
        print "action:", action_name, dbname, fieldname, condition_limit
        # insert into staff (name, dept, phone, eroll_date) values (li, DEV, 123456677, 20110101)
        write_file(dbname, fieldname, condition_limit, condition_values)
    
    def delete(action_name, dbname, fieldname, condition_limit, condition_values):
        print "action:", action_name, dbname, fieldname, condition_limit
    
    def update(action_name, dbname, fieldname, condition_limit, condition_values):
        print "action:", action_name, dbname, fieldname, condition_limit
    
    def select(action_name, dbname, fieldname, condition_limit, condition_values):
        print "action:", action_name, dbname, fieldname, condition_limit
        read_file(dbname, fieldname, condition_limit)
    
    def read_file(fname, fieldname, condition_limit):
        with open(fname, "r") as fd:
                for line in fd:
                    if fieldname == "*" and condition_limit == "no":
                        print line.strip("
    ")
                    elif fieldname == "*" and condition_limit != "no":
                        condition_item = condition_limit.strip(";").split()[0].strip('"')
                        condition_signal = condition_limit.strip(";").split()[1]
                        condition_value = condition_limit.strip(";").split()[2].strip('"')
                        if condition_item == "name" and condition_signal == "=":
                            if line.strip("
    ").split(",")[1] == condition_value:
                                print line.strip("
    ")
                        elif condition_item == "dept":
                            if line.strip("
    ").split(",")[2] == condition_value:
                                print line.strip("
    ")
                        elif condition_item == "eroll_date" and condition_signal == "like":
                            if line.strip("
    ").split(",")[4].__contains__(condition_value):
                                print line.strip("
    ")
    
    
    def get_last_line(fname):
        block_size = 1024
        with open(fname, "r") as fd:
            file_size = os.path.getsize(fname) 
            if file_size > block_size:
                seek_point = (file_size // block_size)
                fd.seek((seek_point - 1) * file_size)
            else:
                fd.seek(0, 0)
            lines = fd.readlines()
            if lines:
                last_line = lines[-1].strip()
            print last_line    
        return last_line
    
    def write_file(fname, fieldname, condition_limit, condition_values):
        with open(fname ,"a+") as fd:
            last_line = get_last_line(fname) 
            cur_max_id = last_line.split(",")[0]
            print cur_max_id
            item = ",".join(condition_values.split(","))
            record = re.sub(r'"| ', "", item.strip()).strip("(").strip(")")
            record_id = int(cur_max_id) + 1
            fd.writelines(str(record_id) + "," + record)
    

    文件名: mock_sql.py

    # coding:utf-8
    
    '''
    sql_func是导入的另外一个模块,即位于同级目录的sql_func.py
    
    需求语法:
        insert into tablename
        delete from tablename
        delete from tablename where clause
        update tablename set filedname=value
        update tablename set (fieldname1, fieldname2, fieldname3...) values (val1, val2, val3...)
        select * from tablename where clasuse
        select filedname from tablename where clause
    '''
    
    import re
    import sql_func
    
    def parse_user_rawinput(func):
        # 拆分字符串获得表名的正则表达式
        re_parse_dbname = r"' '+|from|update|into"
        # 拆分字符串获得字段名的正则表达式
        re_field_name = r"select|from|set|where|into|values|="
        # 拆分字符串获得where条件的正则表达式
        re_condition = r"where"
        # 拆分是insert into插入记录的情况下的values的正则表达式
        re_insert_values = r"values"
        def wrapper_parse(user_input):
            user_action_pointer, user_line, user_sql = func(user_input)
            if user_action_pointer in ["select", "delete","insert", "update"]:
                user_action_pointer, user_sql, user_line = func(user_input)
                dbname = re.split(re_parse_dbname, user_line)[1].lstrip().split()[0].rstrip(";")
                fieldname = re.sub(r"(^.* )(", "", re.split(re_field_name, user_line)[1]).strip(" )")
                if user_action_pointer in ["select", "delete", "update"]:
                    condition = re.split(re_condition, user_line)
                    if len(condition) == 1:
                        condition_limit = "no"
                    else:
                        condition_limit = condition[1]
                elif user_action_pointer == "insert":
                    condition_limit = "no"
                    condition_values = re.split(re_insert_values, user_line)[1]
                sql_action(user_action_pointer, dbname, fieldname, condition_limit, condition_values)
            else:
               print  "invalid action"
               return "invalid action"
               exit(1)
        return wrapper_parse
    
    @parse_user_rawinput
    def parse_user_input(user_input):
        user_action_pointer = user_input["user_sql_list"][0]
        user_sql = user_input["user_sql_list"]
        user_line = user_input["user_line"]
        return user_action_pointer, user_sql, user_line
    
    def sql_action(action_name, dbname, fieldname, condition_limit, condition_values):
        if action_name in ["select", "insert", "update", "delete"]:
            if hasattr(sql_func, action_name):
                func = getattr(sql_func, action_name)
                result = func(action_name, dbname, fieldname, condition_limit, condition_values)
    
    def input():
        user_results = dict()
        user_line = raw_input("input your sql:")
        user_sql_list = user_line.rstrip(";").split()
        user_results["user_line"] = user_line
        user_results["user_sql_list"] = user_sql_list
        return user_results
    
    if __name__ == "__main__":
        user_input = input()
        parse_user_input(user_input)
    
    

    1,zhang,DEV,13600010001,20100101
    2,wang,DEV,1360020002,20110101
    3,zhao,OPS,13600030005,20110201
    4,qian,OPS,13600040006,20130203
    5,sun,OPS,13600050007,20070709
    6,li,OPS,13600060008,20150602
    7,wu,OPS,13600070009,20160703

  • 相关阅读:
    有關window.showModalDialog的應用11/30
    phpmyadmin的查詢不出現10/29
    那點事情我沒有精力做10/17
    水晶報表System.InvalidCastException: 指定的轉換無效11/30
    水晶報表匯出時System.InvalidCastException:指定的格式無效10/29
    读博日记(C#常用开源类库收集
    ASP.net通过JQuery实现Ajax操作
    仿Discuz!的论坛评分发帖弹出提示并渐渐消失的效果
    仿Discuz文本框弹出层的效果
    C#开源资源大汇总
  • 原文地址:https://www.cnblogs.com/haozike/p/python_decorator_example.html
Copyright © 2011-2022 走看看