现在已经把项目开源出来,框架名为dophon,有兴趣的话可以点击框架文档进入查看
项目地址:https://github.com/Ca11MeE/easy_frame.git
- 闲来无事,公司要求做小程序,写完前端,获取数据时遇见难题,后台服务器用java写吧,环境部署真是个费劲活(主要没有环境包,这个真是日积月累的懒)
- 想起了python,虽然我哭,但是不短好吧,以前也就是做一做数据过滤脚本,从论坛copy一两个代码改一改玩一下数据挖掘啊(那个什么meizi**.com之类的,完全是兴趣),或者是帮我同学做作业(是的,他是研究生,我是程序员)搞一下分词,流处理,导出云词图之类的,或者写一个飞机大战,坦克大战,XX大战的demo(其实都是拷贝源码,真是惭愧,GUI我止步与创建窗口和一个按钮,你没听错,一个按钮)
- 正好以前看了看Flask,照着demo敲了一下,同时懒得学django,就决定了Flask了!!!!
- 顺便提一下,数据库用pymysql,然后没有了
- 用顺手了Spring,越写越别扭好吧,不得不说Spring的框架简直造福大众,于是踏上python模拟Sping的部分功能之路(你没看错,是模拟,我不敢说完全一样,主要python本身语言属性和java就不一样,我只是去开发出我所需要的功能而已,我也,没这个实力去写一套人皆可用的架构,没这么吊,真的没这么吊)
- 再顺带一说,我写了一个连接池(仅仅是一个池,其实就是一个栈,跳过吧好吧,谁都可以写)
- 嗯,还模仿了mybatis的xmlsql这个我一直觉得很方便的功能,以后尝试一下远程读取sql语句,还有ssl形式读取(后面统一整理一下)
- 关于源码或者开源路径什么的,有需要就下方评论,若是有更好想法,欢迎提出
- 假如有什么诸如(为什么要用python搞这样的事情 + 理由,或者直接用现成的ssm框架不行吗,怎么非得要用python自己写轮子,又或者理由+python是动态语言,你这样违背了XX原则 or 你这样就不python了)这样的观点,欢迎发表评论,可能看官您看到上面某一条突然火大,跑去下面评论了,可以理解
- 关于上一条,这种东西如同”榴莲是世界上最难吃的东西/榴莲这种物种就不应该存在”这种问题是不会有得出结果的一刻的,你们可以尽情的怪我不去回复
- 暂时没有,后期会不定时更新的放心,我还是很经常的维护博客的,就是没怎么发文章而已
截止发表文章,完成的有
- @ResponseBody():包装了Flask的jsonify()的init方法,需要返回json格式数据
- 数据库部分功能:
– 语句执行调试功能
– 数据库连接池
– xml读取模块
– sql参数拼接模块(只支持简单值,现在逻辑上只支持str)
– 分页查询模块(算是上一条的附加吧)
– 远程xmlsql获取(xml文件传输,使用uuid多层文件夹,略骚气的无关操作)
– 定时热更新XML文件以及内存SQL语句
– 远程定时同步文件(滥用会阻塞ftp连接哟),暂时以分钟为间隔单位
– 定时什么的用的是调度
基础问题
1. @问题
1.1 @这个东西很是神奇
首先说个前提,我是从JAVA转到Python的,什么《XX速成》《从XX到XX》我真没怎么看,知道大概语法规则就开干了
JAVA里面注解的作用给我感觉主要是标注(归咎于我用的最多的AOP),说实话更深层次的注解应用我真没接触过,Spring博大精深很多源码到现在都不敢点开(还是看过一部分的),此处JAVA中的注解就以AOP为例吧(起码比较有代表性,各位接触的也很多)
废话不多说,上干货
Python里面的@较于JAVA更倾向于装饰(没有Java中代理那么繁琐复杂,好吧我说的是一些语法结构和代码追溯上),直接的简单明了的去代理一个方法(还有粗暴),基于语言的动态特性,通常在使用过程中或者刚上手的一段时间内会觉得简直反人类,不过只要记住:
装饰器这种东西如同链式调用
这句话就基本心里有一定概念了
项目代码为例:
# 获取顶部标题栏
@_app.route('/tabs', methods=['GET'])
@annotation.ResponseBody()
def hello():
result = _SGCobj.getHeadTitle()
return result
请忽略注释以及对象名balabala,注意两个注解,在JAVA-Spring开发中,注解的链式概念并不太明显(除非你的注入是有很强的目的性或者对原来流程有很强的因果侵入),相信各位使用的AOP基本都是实现系统中的一些共有抽象功能,比如登录检测,日志打印,参数整理,参数检测,等等等等,但是在Python中的装饰器是有很严格的链式规则的,如果上面代码去掉了@annotation.ResponseBody()
那么在访问’/tabs’路径的时候,Flask会报错(找不到对应页面),这是因为返回的结果被视图解析器处理了
当然,直接返回响应体不是不可以,每个return中的返回结果被一个jsonify()包装起来效果其实一毛一样,不过看起来总有点不爽就是了,不如一个装饰器来的直接
说回链式这个话题,如果上面代码两个装饰器换个位置,变成这样
# 获取顶部标题栏
@annotation.ResponseBody()
@_app.route('/tabs', methods=['GET'])
def hello():
result = _SGCobj.getHeadTitle()
return result
问题就来了,对于一个
@a()
@b()
def c():
pass
链式调用其实就是:a(b(c()))
互换位置的结果如同去掉@annotation.ResponseBody()
(这次不敢说一毛一样),返回的结果被试图解释器处理了,Flask报出找不到页面的错误(404)
题外话:
在开发过程中发现了一个问题,单纯的用装饰器装饰Flask的路由装饰内的方法会抛出重复结束点的错误(弄了我一晚上),最后参照网上解决方法处理了(不知道完不完美),具体下面会说.急不可耐的同学可以直接复制错误百度一下
装饰器的定义方法有两种:
第一种是无参装饰器定义:
def a(f,*arg,**kwargs):
def method():
return f(arg,kwarg)
return method
第二种是带参装饰器定义(位置参数和关键字参数都无妨):
def a(arg1,arg2,arg3,....):
def method(f):
def m_args(*args,**kwargs):
return f(args,kwargs)
return m_args
return method
简单来说,第一种=入门,第二种=进阶
先来说说装饰器的基本流程
首先调用被装饰的方法时会先调用装饰器定义的方法
装饰器方法内部需要显式定义被装饰方法的模板(也就是第一层的代码里面定义的方法)
装饰器内部需要返回被装饰方法的模板名(记住不带括号),其实也可以不用返回,不过python要求函数体,你可以试下写个pass(其实这里也有很强的因果侵入)
首先从入门开始说起
无参定义简单很多,a方法里面的参数分别指:
f ==> 被装饰的方法
*arg ==> 被装饰方法的位置参数集合
**kwargs ==> 被装饰方法的关键字参数集合
未完待续…