计算数独

python3 装饰器

  很久没在博客园写文章了,打算把一直由自己一个人写的一整套系统开放出来,今天先放一些截图及可以演示的地址!

数独文件

000000002
006002000
000030040
000050000
001000006
000400070
050000000
000003109
470009000

一、闭包

闭包的两个条件:函数内套有内层函数;内层函数引用外层函数定义的变量。

eg:

def outer():

    x=10

    def inner():

    print(x)

    return inner

这套系统包含数据层(HB.Data)、计划任务(HB.PlanTask)、日志系统(HB.Log)、模版系统(HB.TemplateEngine)、Url重写(HB.UrlRewriter)、api(HB.ApiControls)等。

代码

class Sudoku:
    ALL = set(range(1, 10))

    def __init__(self, sdk_file):
        self.sdk_matrix = [[int(c) for c in line]
                           for line in sdk_file.read().split("\n")] if sdk_file else []

    def get_row(self, row):
        return self.sdk_matrix[row]

    def get_col(self, col):
        return [row[col] for row in self.sdk_matrix]

    def get_matrix(self, row, col):
        sr, sc = (row // 3) * 3, (col // 3) * 3
        for r in range(sr, sr + 3):
            for c in range(sc, sc + 3):
                yield(self.sdk_matrix[r][c])

    def get_avls(self, row, col):
        return self.ALL - (set(self.get_matrix(row, col)) | set(self.get_row(row)) | set(self.get_col(col)))

    def __getitem__(self, n):
        return self.sdk_matrix[n]

    def __str__(self):
        return "\n".join([str(row) for row in self.sdk_matrix])

    def clone(self):
        sdk_c = Sudoku(None)
        for row in range(9):
            sdk_c.sdk_matrix.append([])
            for col in range(9):
                sdk_c.sdk_matrix[row].append(self.sdk_matrix[row][col])
        return sdk_c


def get_answer(sdk):
    has_filled, brunch = False, None
    for row in range(9):
        for col in range(9):
            if sdk[row][col] != 0:
                continue
            avls = sdk.get_avls(row, col)
            if len(avls) == 0:
                return False
            elif len(avls) == 1:
                sdk[row][col] = avls.pop()
                has_filled = True
            elif not brunch or len(avls) < len(brunch[0]):
                brunch = (avls, row, col)
    if has_filled:
        answer = get_answer(sdk)
        if answer:
            return answer
    elif brunch:
        for b in brunch[0]:
            sdk_c = sdk.clone()
            sdk_c[brunch[1]][brunch[2]] = b
            answer = get_answer(sdk_c)
            if answer:
                return answer
    else:
        return sdk


with open("4.sdk") as sdk_file:
    sdk = Sudoku(sdk_file)
    answer = get_answer(sdk)
    print(answer)

二、装饰器

装饰器是为了在不改变原先函数源码的前提下,增加功能而存在的。执行流程:在调用被装饰器修饰的函数时,装饰器会先被调用,将被装饰函数的函数名传入装饰器函数,执行装饰器内层函数,内层函数会调用被装饰函数,从而实现被装饰函数的执行,而增加的功能在内层函数里写着,所以增加的功能也实现了。这样做的好处是,被装饰的函数的调用方法不变,从而防止牵一发而动全身的现象出现;没有改变被装饰函数的源码,符合开放封闭原则。

注意,装饰器函数必须是闭包函数。

eg:

装饰器函数:

import time
def show_time(f):
    def inner(*args,**kwargs):     
#设定不定长参数,防止被装饰函数有参数
        start_time=time.time()
        f(*args,**kwargs)
        time.sleep(3)
        end_time=time.time()
        print(‘spend_time=%s’%(end_time-start_time))
    return inner()

 

@show_time

def foo():           #被装饰器修饰的函数

    print('ok')

foo()#调用函数

如果需要向装饰器函数中传参则在装饰器函数外围在套一层外部函数。

eg2:

def outer(*args):

    def show_time(f):

          def inner(*args,**kwargs):

               pass

         return inner

return show_time

 

@outer(‘参数’)

def foo ():

    pass

 

foo()#调用函数

  为什么要写数据层呢?现成的ORM不是一大堆吗,为什么还要自己写?多年前,dotNet里并没有什么ORM,很多东西都只能自己写,慢慢的数据层功能也就越来越强大了,

结果

图片 1

可以通过实体类来生成数据库中的表,也可以通过数据库中的表来生成数据库,并且支持多中数据库,比如Sql
Server、Access、Sqlite、Oracle、MySql等。数据层有通用的增删改查方法,并且支持参数化的写法,实体类里还有表达式的写法(注:表达式的写法暂时支持不完善)!

流程图

图片 2

  Url重写的主要改进是支持通过数据库来配置域名及重写规则,并且支持多域名的形式。比如说我只买了一个空间,但是我有好几个网站,该功能就可以实现一个空间上就可以做多个网站的功能!您可以试一试www.8fdc.com、www.54rm.com、www.5wshop.com,看到的结果都是不一样的,因为重写了路径,www.8fdc.com实际上是进入的站点下8fdc.com/www/
下的,依次类推,当然这个是可以通过数据库来配置。

  api的功能主要实现了参数自动匹配,直接在后台类中写方法,以 /api/类名前缀/方法名称.ashx
的形式进行访问。

     先直接上整套系统的图片把,看看反响,在最后面开放网站后台演示地址!

 

图片 3

图片 4

发表评论

电子邮件地址不会被公开。 必填项已用*标注