【python零基础入门学习】python基础篇之系统模块调用shell命令执行(四)
本站以分享各种运维经验和运维所需要的技能为主
《python》:python零基础入门学习
《shell》:shell学习
《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战
《k8》暂未更新
《docker学习》暂未更新
《ceph学习》ceph日常问题解决分享
《日志收集》ELK+各种中间件
《运维日常》持续更新中
系统管理模块:
shutil模块:
用于执行一些shell操作
import shutil
import os
f1 = open('/etc/hosts', 'rb')
f2 = open('/tmp/zj.txt', 'wb')
shutil.copyfileobj(f1 , f2)
f1.close()
f2.close()#拷贝文件,cp /etc/hosts /tmp/zhuji
shutil.copy('/etc/hosts','/tmp/yff')
shutil.copy('/etc/hosts','/tmp/yff.txt')#cp -p /etc/hosts /tmp/zhuji
shutil.copy2('/etc/hosts','/tmp/yff2')#cp -r /etc/security /tmp/anquan
shutil.copytree('/etc/security','/tmp/anquan')#mv /tmp/anquan /var/tmp/
shutil.move('/tmp/anquan','/var/tmp')#chown bob.bob /tmp/yyf
shutil.chown('/tmp/yff.txt',user='yyf',group='yyf')
shutil.chown('/tmp/yff',user='yyf',group='yyf')
shutil.chown('/tmp/yff2',user='yyf',group='yyf')#rm -rf /var/tmp/anquan ---只能删除目录
shutil.rmtree('/var/tmp/anquan')
#rm -rf /tmp/yyf ----删除文件
os.remove('/tmp/yff2')
subprocess模块:
用于调用系统命令
>>> import subprocess
>>> result = subprocess.run('id root', shell=True)
uid=0(root) gid=0(root) 组=0(root)>>> result = subprocess.run('id root ; id yyf', shell=True)
uid=0(root) gid=0(root) 组=0(root)
uid=1003(yyf) gid=1003(yyf) 组=1003(yyf)>>> result = subprocess.run('id root ; id ddd', shell=True)
uid=0(root) gid=0(root) 组=0(root)
id: ddd: no such user>>> result.args
'id root ; id ddd'>>> result.returncode -----相当于 shell 的$?
1#如果不希望把命令的执行结果打印在屏幕上,可以使用以下方式:
>>> import subprocess
>>> result = subprocess.run('id root; id sss', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> result.stderr
b'id: sss: no such user\n'
>>> result.stdout
b'uid=0(root) gid=0(root) \xe7\xbb\x84=0(root)\n'
>>> result.stdout.decode()
'uid=0(root) gid=0(root) 组=0(root)\n'
>>>py:
import subprocess
result = subprocess.run('id root ; id fff ', shell=True, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
print(result.stderr)
print(result.stdout)
print(result.stdout.decode())测试结果:
b'id: fff: no such user\n'
b'uid=0(root) gid=0(root) \xe7\xbb\x84=0(root)\n'
uid=0(root) gid=0(root) 组=0(root)
ping脚本:
import sys
import subprocessdef ping(host):result = subprocess.run('ping -c2 %s &> /dev/null' % host , shell=True)if result.returncode == 0 :print('%s:up' % host)else:print('%s:down' % host)if __name__ == '__main__':ping(sys.argv[1])
编程常用语法风格以及习惯:
语法风格:
链示多重赋值:
>>> a=b=[10,20]
>>> b.append(40)
>>> a
[10, 20, 40]
>>> b
[10, 20, 40]
多元变量赋值:
>>> a,b = 10 ,20
>>> a
10
>>> b
20
>>> c, d = (10,20)
>>> c
10
>>> d
20
>>> e, f = [10, 20 ]
>>> e
10
>>> b
20
>>> a = [100]
>>> a
[100]
>>> g, f = 'ab'
>>> g
'a'
>>> f
'b'两个变量互换>>> t = a
>>> a = b
>>> b = t
>>> a
20
>>> b
[100]
>>> a , b = b ,a
>>> a
[100]
>>> b
20
合法标识符:
>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
>>> 'pass' in keyword.kwlist
True
>>> keyword.iskeyword('is')
True
內建:
內建不是关键字,可以被覆盖,除非你不用它
len = 100
len('abc') -----无法使用原来的功能
模块文件布局:
```python
#!/usr/local/bin/python3 # 解释器
"""模块文件名模块文件的说明文字,即文档字符串,用于help帮助
"""
import sys # 模块导入
from random import randint, choicehi = 'Hello World' # 全局变量
debug = Trueclass MyClass: # 类的定义passdef func1(): # 函数定义passif __name__ == '__main__': # 主程序代码func1()
```
#!/usr/local/bin/python3 ---解释器
"""演示模块辣鸡
"""
hi = 'hello shabichao' # 全局变量之后才可以调用def pstar(n=30):"用于打印n个星号"print('*' * n)if __name__ == '__main__':print(hi)pstar()pstar(50)>>> import star
>>> help(star)
Help on module star:
NAMEstar - 演示模块
DESCRIPTION辣鸡
FUNCTIONSpstar(n=30)用于打印n个星号
DATAhi = 'hello shabichao'
FILE/root/nsd1907/py01/day03/star.py
判断文件是否存在:
>>> import os
>>> os.path.ex
os.path.exists( os.path.expanduser( os.path.expandvars( os.path.extsep
>>> os.path.ex
os.path.exists( os.path.expanduser( os.path.expandvars( os.path.extsep
>>> os.path.exists('/tmp/yff')
True
>>> os.path.exists('/tmp/yffdd')
False
编程思路:
1. 发呆。思考程序的动作方式(交互?非交互?)
```shell
文件名: /
文件已存在,请重试。
文件名: /etc/hosts
文件已存在,请重试。
文件名: /tmp/abc.txt
请输入文件内容,在单独的一行输入end结束。
(end to quit)> hello world!
(end to quit)> how are you?
(end to quit)> the end
(end to quit)> end
# cat /tmp/abc.txt
hello world!
how are you?
the end
```
2. 分析程序有哪些功能,把这些功能编写成函数
```python
def get_fname():'用于获取文件名'
def get_content():'用于获取内容'
def wfile(fname, content):'用于将内容content,写入文件fname'
```
3. 编写程序的主体,按一定的准则调用函数
```python
def get_fname():'用于获取文件名'
def get_content():'用于获取内容'
def wfile(fname, content):'用于将内容content,写入文件fname'
if __name__ == '__main__':fname = get_fname()content = get_content()wfile(fname, content)
```
4. 完成每一个具体的函数
实例:
"""创建文件这是一个用于创建文件的脚本,用到的有三个函数
"""
import osdef get_fname():'用于获取文件名'while 1 :fname = input('文件名: ')if not os.path.exists(fname):breakprint('文件已存在,请重新输入: ')return fnamedef get_content():'用于获取内容'content = []print('请输入文件内容,在单独的一行输入end结束')while 1:line = input('(end to quit)> ')if line == 'end':break#content.append(line + '\n')content.append(line)return content# print('请输入文件内容,在单独的一行输入end结束')# f = open(fname,'w')# while if q != end :# content = f.writelines([q = input('(end to quit)>: ')])def wfile(fname,content):'用于将内容content,写入文件fname'with open(fname, 'w') as fobj:fobj.writelines(content)# fobj = open(fname,'w')# fobj.writelines(content)# fobj.close()if __name__ == '__main__':fname = get_fname()content = get_content()print(content)content = ['%s\n' % line for line in content]wfile(fname, content)
序列对象:
包括字符串 列表 元组
#list用于将某些数据转成列表
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list('abc')
['a', 'b', 'c']
#tuple用于将某些数据转成元组
>>> tuple('abc')
('a', 'b', 'c')
>>> tuple(range(10))
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)>>> len('asdasd')
6#reversed 用于翻转
>>> alist = [ 10 , 8 , 25 , 1, 100]
>>> list(reversed(alist))
[100, 1, 25, 8, 10]
>>> for i in reversed(alist):
... print(i)#sorted用于排序,默认升序
>>> sorted(alist)
[1, 8, 10, 25, 100]#enumerate 用于获取下标和值
>>> user = ['tom','yyf','chao']
>>> list(enumerate(user))
[(0, 'tom'), (1, 'yyf'), (2, 'chao')]
>>> for i in enumerate(user):
... print(i)
...
(0, 'tom')
(1, 'yyf')
(2, 'chao')
>>> for i, name in enumerate(user):
... print(i,name)
...
0 tom
1 yyf
2 chao
>>> print(i) ------一次次的赋值给变量i
2
字符串:
格式化操作符:
>>> '%s is %s years old' % ('tom',20)
'tom is 20 years old'
>>> '%s is %d years old' % ('tom',20)
'tom is 20 years old'
>>> '%s is %f years old' % ('tom',20.5)
'tom is 20.500000 years old'
>>> '%s is %d years old' % ('tom',20.5)
'tom is 20 years old'
>>> '%d is %d years old' % ('tom',20) -----tom转不成数字
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: %d format: a number is required, not str
>>> '%s is %.1f years old' % ('tom',20.5) ------%.1f 指保留1位小数
'tom is 20.5 years old'>>> '%10s%8s' % ('tom',20.5) -----正数向右对齐
' tom 20.5'
>>> '%10s%8s' % ('tom','age')
' tom age'
>>> '%-10s%-8s' % ('tom','age') ------负数向左对齐
'tom age '
>>> '%-10s%-8s' % ('tom',20)
'tom 20#不常用 了解
>>> '%c' % 97 ----将数字根据ascii码转成对应的字符
'a'
>>> '%c' % 65
'A'
>>> '%#o' % 10----8进制
'0o12'
>>> '%#x' % 10------16进制
'0xa'
>>> '%e' % 10000-----科学计算法----
'1.000000e+04' ------e+04 10的4次方
>>> '%8d' % 10
' 10'
>>> '%08d' % 10 -----宽度8 不够的补0
'00000010'format函数
>>> '{} is {} years old'.format('tom',20)
'tom is 20 years old'
>>> '{1} is {0} years old'.format('tom',20)
'20 is tom years old'
format函数:
创建用户:
"""创建用户这是一个用于创建用户的脚本,用到有4个函数
"""import sys
import randpass
import subprocessdef add_user(user, passwd, fname):#如果用户已存在,则返回,不要继续执行函数result = subprocess.run('id %s &> /dev/null' % user, shell=True)if result.returncode == 0 :print('用户已存在')#return默认返回None,类似于break,函数遇到return也会提前结束return# 创建用户, 设置密码subprocess.run('useradd %s' % user, shell=True)subprocess.run('echo %s | passwd --stdin %s' % (passwd,user),shell=True)#写入文件info = """用户信息:用户名: %s密码: %s""" % (user,passwd)with open(fname,'a') as fobj:fobj.write(info)if __name__ == '__main__':user = sys.argv[1]passwd = randpass.mk_pass2()fname = sys.argv[2]add_user(user,passwd,fname)
原始字符串操作符:
>>> win_path = 'c:\temp'
>>> print(win_path)
c: emp
>>> wpath = r'c:\temp'
>>> print(wpath)
c:\temp
>>> win_path = 'c:\\temp'
>>> print(win_path)
c:\temp
>>> a = r'c:\tem\tec'
>>> print(a)
c:\tem\tec
格式化输出:
>>> '+%s+' % ('*' * 50)
'+**************************************************+'
>>> 'hello world'.center(48)
' hello world '
>>> '+hello world+'.center(50)
' +hello world+ '
>>> '+%19s%-18s+' % ('hello','world')
'+ helloworld +'>>> 'hello world'.center(48,'*')
'******************hello world*******************'
>>>
>>> 'hello world'.ljust(48,'a')
'hello worldaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
>>> 'hello world'.ljust(48,'#')
'hello world#####################################'
>>> 'hello world'.rjust(48,'%')
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%hello world'
>>>
>>> '+' + 'hello world'.center(48,'*') + '+'
'+******************hello world*******************+'
>>> '+%s+' % 'hello'.center(50)
'+ hello +'>>> 'hello'.upper() # 转大写
'HELLO'
>>> 'HELLO'.lower() # 转小写
'hello'
>>> 'hello'.startswith('h') # 字符串以h开头吗?
True
>>> 'hello'.startswith('he') # 字符串以he开头吗?
True
>>> 'hello'.endswith('ab') # 字符串以ab结尾吗?
False
>>> 'hao123'.islower() # 字母都是小写的吗?
True
>>> 'hao123'.isupper() # 字母都是大写的吗?
False
>>> '1234'.isdigit() # 所有的字符都是数字吗?
True# 判断是不是所有的字符都是数字字符
>>> s = '1234@11'
>>> for ch in s:
... if ch not in '0123456789':
... print(False)
... break
... else:
... print(True)
...
False
下一篇文将会教python的常用数据类型:列表,元组,字典,集合,想学习的同学一起学习。
相关文章:
【python零基础入门学习】python基础篇之系统模块调用shell命令执行(四)
本站以分享各种运维经验和运维所需要的技能为主 《python》:python零基础入门学习 《shell》:shell学习 《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战 《k8》暂未更新 《docker学习》暂未更新 《ceph学习》ceph日常问题解…...
用python实现基本数据结构【01/4】
说明 如果需要用到这些知识却没有掌握,则会让人感到沮丧,也可能导致面试被拒。无论是花几天时间“突击”,还是利用零碎的时间持续学习,在数据结构上下点功夫都是值得的。那么Python 中有哪些数据结构呢?列表、字典、集…...
Ubuntu22.04 install Kafka
kafka quickstart install kafka...
实现JSONP请求
同源策略 JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。 而所有非同源的请求(即 域名,协议,端口 其中一种或多种不相同),都会被作为跨域请求。实际上请求…...
如何将安防视频监控系统/视频云存储EasyCVR平台推流到公网直播间?
视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同,支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强,视频能力丰富,具体可实现视频监控直播、视频轮播、视频录像、…...
使用内网负载机(Linux)执行Jmeter性能测试
一、背景 在我们工作中有时候会需要使用客户提供的内网负载机进行性能测试,一般在什么情况下我们需要要求客户提供内网负载机进行性能测试呢? 遇到公网环境下性能测试达到了带宽瓶颈。那么这时,我们就需要考虑在内网环境负载机下来执行我们…...
Web自动化测试进阶 —— Selenium模拟鼠标操作
鼠标操作事件 在实际的web产品测试中,对于鼠标的操作,不单单只有click(),有时候还要用到右击、双击、拖动等操作,这些操作包含在ActionChains类中。 ActionChains类中鼠标操作常用方法: 首先导入ActionChains类&…...
Python之函数
函数是什么? 函数是对程序逻辑进行结构化或过程化的一种编程方法,将整块代码巧妙地隔离成易于管理的小块。把重复代码放到函数中而不是进行大量的拷贝,这样既能节省空间,也有助于保持一致性;通常函数都是用于实现某一种…...
泛型工具类型和操作符
前言 TypeScript 内置了一些常用的工具类型。 PartialRequiredOmitPick.... 操作符 typeof typeof 操作符可以用来获取一个变量声明或对象的类型 const p {x:2,y:cm} let g:typeof p {x:3,y:ff} 这里g需要满足: 有x属性且值是number类型 有y属性且值是string类型…...
idea中启动maven项目报错-java: 程序包lombok.extern.slf4j不存在问题如何解决
1、 现象: 在springboot的maven项目启动时,报错: Error:(3, 27) java: 程序包lombok.extern.slf4j不存在 编译不报错,maven依赖也合适,项目就是无法启动 原因: 其实不是项目本身或者maven本身的问题&am…...
MyBatis-动态SQL
<if>标签 用于判断条件是否成立,使用test属性进行条件判断,如果条件为true,则拼接SQL <where>标签 where元素只会在子元素有内容的情况下插入where子句,而且会自动去除子句的开头的AND或OR <where><if tes…...
Swift学习内容精选(二)
Swift 类是构建代码所用的一种通用且灵活的构造体。 我们可以为类定义属性(常量、变量)和方法。 与其他编程语言所不同的是,Swift 并不要求你为自定义类去创建独立的接口和实现文件。你所要做的是在一个单一文件中定义一个类,系…...
类欧笔记存档
电子版:https://blog.csdn.net/zhangtingxiqwq/article/details/132718582...
电能计量远程抄表系统的分析及在物业的应用
安科瑞 华楠 摘 要:结合当前电力企业实际的发展概况,可知电力活动开展中对于性能可靠的电能计量及远程抄表依赖程度高,需要注重它们实际应用范围的扩大,满足电力企业长期稳定发展的实际需求。基于此,本文将对电能计量…...
计算机网络篇之端口
计算机网络篇之端口 文章目录 计算机网络篇之端口前言概括分类总结 前言 我们知道ip地址可以确定向哪台主机转发数据,但是数据要发给主机的哪个进程,这个时候端口就派上用场了 概括 计算机网络端口是用于区分不同应用程序或网络服务的逻辑地址&#x…...
GO语言篇之发布开源软件包
GO语言篇之发布开源软件包 文章目录 GO语言篇之发布开源软件包新建仓库拉取到本地初始化项目编写代码提交代码发布引用软件包 我们写GO语言程序的时候难免会引用第三方的软件包,那么你知道别人是怎么发布自己的软件包吗,别急,这篇博客教你怎么…...
Eclipse官网下载历史版本
进入官网 https://www.eclipse.org/ 进入下载页面 选择下载包 同一版本,又有不同类型 Eclipse IDE for Enterprise Java and Web Developers Eclipse IDE for Java Developers 任何Java开发人员必备的工具,包括Java IDE、Git客户端、XML编辑器、Mave…...
SCI常见词汇表达
一.被认为 is known to;it is known thatbe regarded asis characterized byis believed toit is generally acknowledged thathave been implicatedit has been shown that 二.表明 revel ; demonstrate ; appeared toreport ; considered as ; uncoverfound ; show ; impl…...
使用ref如何获取到input标签中的值
要使用 ref 获取到 input 标签中的值,首先需要创建一个 ref 对象并将其绑定到 input 标签上。然后,可以通过访问 ref 对象的 value 属性来获取标签中的值。 下面是一个示例代码: import React, { useRef } from react; function App() {cons…...
自定义Dynamics 365实施和发布业务解决方案 3. 开箱即用自定义
在本章中,您将开始开发SBMA会员应用程序。在开发的最初阶段,主要关注开箱即用的定制。在第2章中,我们讨论了如何创建基本解决方案的细节,在本章中,将创建作为解决方案补丁的基本自定义,并展示将解决方案添加到源代码管理和目标环境的步骤。 表单自定义 若要开始表单自定…...
python-pytorch 关于torch.load()和torch.load_state_dict()
python-pytorch 关于torch.load和torch.load_state_dict 1、关于模型保存和加载2、关于加载模型结构 最近在使用pytorch训练和加载模型时遇到了一些很玄学的问题,研究了一下,总结如下: 1、关于模型保存和加载 1、如果保存时使用了torch.save…...
关于批量安装多个apk
for %i in (apks地址/*.apk); do adb install %i https://www.cnblogs.com/lihongtaoya/p/15084378.html adb install -r apks地址/1.apk && adb install -r apks地址/2.apk install-multi-package - 暂时nok https://adbshell.com/commands 最新版本的platform-tool…...
【案例教学】华为云API对话机器人的魅力—体验AI垃圾分类机器人
云服务、API、SDK,调试,查看,我都行 阅读短文您可以学习到:人工智能AI自言语言的情感分析、文本分词、文本翻译 1 IntelliJ IDEA 之API插件介绍 API插件支持 VS Code IDE、IntelliJ IDEA等平台、以及华为云自研 CodeArts IDE&a…...
go基础详解2-go run test
一 go run 编译运行一个main 包(package),常用的运行方式如下: go run . go run hello go run 后面接路径,该路径(不含子路径)下所有的go源文件都属于main包。 go run filename1 filename1 …...
【NVIDIA CUDA】2023 CUDA夏令营编程模型(三)
博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。 博客…...
字节8年经验之谈 —— 冒烟测试、回归测试是什么?
冒烟测试(Smoke Testing)和回归测试(Regression Testing)是软件测试中常用的两种测试类型。 冒烟测试(Smoke Testing):冒烟测试是在软件开发的早期阶段进行的一种表面级功能验证测试。它主要用…...
FP6102 20V、3A降压开关调节器芯片
FP6102 20V、3A降压开关调节器芯片 一般说明 FP6102是一种用于广泛工作电压应用领域的降压开关调节器。FP6102包括高电流P-MOSFET,用于将输出电压与反馈放大器进行比较的高精度参考(0.5V),内部死时间控制器和用于控制最大占空比和…...
魔众携手ModStart上线全新模块市场,支持模板主题
ModStart模板主题 对于很多新手或者是缺乏经验的开发者来说,快速建站具有一定的难度,总是一件让人头疼的问题。 ModStart为开发者提供了一些模板主题供开发者选购使用,模块市场包含了丰富的模块,后台一键快速安装,让开…...
织梦CMS_V5.7任意用户密码重置漏洞复现
一、漏洞说明 织梦内容管理系统(DeDeCMS)以其简单、实用、开源的特点而著名。作为国内最知名的PHP开源网站管理系统,它在多年的发展中取得了显著进步,无论在功能还是易用性方面都有长足的发展。该系统广泛应用于中小型企业门户网站…...
ESP32通过ali的C LINK4.0接入aliyun阿里云
1,通过官网下载C SDK:进入物联网平台:文档和工具 2,选择SDK支持项目:系统为FreeRTOS,单板系统,勾选动态加密,因为测试我把所有的功能都勾选上了。 3,将下载下来的文件放到espSDK下组…...
上海弄网站的/app运营方案策划
在互联网领域,客户端和服务端之间通常需要建立和保持TCP长连接。所谓长连接,就是通信双方在建立TCP连接后进行数据通信,一次或若干次通信交互完成之后,不主动断开连接,而是保持TCP连接不释放,在随时需要通信…...
乾元坤和B2B网站建设解/seo整站优化公司持续监控
String的扩展方法String.prototype.方法名function(){...}基础知识字符串操作和正则表达式的应用一、合并多个空白为一个空白String.prototype.resetBlank function () { return this.replace(/\s/g, " ");}二、过滤空白String.prototype.filterBlank function …...
微商城网站建设效果/友情链接网自动收录
1. 前文 在普遍的也业务系统中, 数据要驱动到操作的用户界面, 它实际储存的方式和表达方式会多种多样, 数据库存储的数字 0或1, 在界面用户看到显示只是 成功或失败, 或者存储的字符、或更多的格式, 但是最终到界面上, 一般是需要一个转换, 至于这个转换是在数据库中, 还是业务…...
岫岩做网站/百度网站推广申请
我试着把一个简单的python脚本(这里我使用了一个随机的两个单词生成器,可以很好地工作)放在一个带有Ajax的网页的div中,下面有一个按钮可以重新加载它。页面成功加载脚本。。。然而,我还没有完全弄清楚丢失的部分,无法再次调用脚本…...
wordpress地址修改错了无法访问/南阳本地网络推广优化公司
微信小程序_[sitemap 索引情况提示] 根据 sitemap 的规则[0],当前页面 [pages/amap/amapindex] 将不被索引 控制台运行是否显示[sitemap 索引情况提示]设置。...
增光路网站建设/公司网站建设方案
github地址:https://github.com/LitePalFramework/LitePal 用过Android原生的数据库也知道,我们要写成千上百行的代码去配置自己的需求,这个是十分痛苦的事件。 第三方的数据库用过greeDao,也是太繁琐,很多需求都需要自己去敲打。…...