命令行工具

ip

1
2
# 查看出口IP(公网IP)
curl icanhazip.com

gnuplot图形化

1
2
3
4
5
6
7
8
9
# 图形化
echo '1
3
2
4
6' | gnuplot -e "set terminal
dumb;plot '<cat' using 1 with line"

awk '{print $1)' /tmp/nginx.log | sort | uniq-c | sort -nr | head -20 | gnuplot -e "set term dumb; plot '<cat using 1:(column(0):ytic(2) with lines;”

xargs

1
2
# xargs捕获whiledo输出,-I {}参数替换,bash -c “cmd string”执行命令
while read line; do xx=$(xxx);echo $xx ;done |xargs -I {} bash -c (sieep 2;adb shell input tap {})

端口占用查看

windows

1
2
3
4
5
6
7
8
# 查看端口
netstat -ano
# 查看pid
netstat -aon|findstr “18082
# 查看进程,可在任务管理器查看
tasklist|findstr “3320
# 结束进程
taskkill /f /t /im httpd.exe

linux

1
2
3
4
5
6
# 列出所有端口的情况
netstat -ano
# 查找占用的程序
netstat -apn | grep 12286
# 杀掉对应进程
kill -9 26105
阅读全文
robotframework安装使用

windows下

相关库包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
pip install requests # http请求
pip install paramiko # 基于SSH用于连接远程服务器并执行相关操作
pip install robotframework
pip install pywin32 # 包装了Windows API
pip install pygments # 代码高亮
pip install robotframework-selenium2library
pip install robotframework-appiumlibrary
selenium2library #selenium2测试库,基于webdriver驱动
geckodriver, chromedriver 和 IEDriverServer # 浏览器驱动,据说45以上的版本Firefox驱动也不再是默认包含
AutoItLibrary # autoit库包,用于进行Windows GUI的自动化操作
pywin32 # windows平台支持,AutoIt的运行环境
autoit # autoit客户端程序,实际运用中,必须装了autoit才能用AutoItLibrary
pip install wxPython # GUI库
pip install robotframework-ride # ride

自定义类库

给Python添加默认路径在Python3X\Lib\site-packages下添加一个路径文件,如mypath.pth,必须以.pth为后缀。文件中直接写上你要加入的模块文件所在的目录名称,可以添加多个目录。

question

1.7.4版本ride使用cmd正常显示中文,使用RIDE执行用例时控制台和日志乱码

1
2
3
4
# 修改Lib\site-packages\robotide\contrib\testrunner\testrunnerplugin.py   def _AppendText    if PY2 else下的
textctrl.AppendTextRaw(bytes(string, encoding['SYSTEM']))
# --》
textctrl.AppendTextRaw(bytes(string, encoding['OUTPUT']))

centos下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 安装相关依赖
yum install gcc-c++
yum -y install gtk2-devel binutils-devel
yum list *gtk+*
yum -y install gtk+.x86_64
yum -y install gtk+-devel.x86_64
yum -y install librcc-gtk+.x86_64
yum -y install gtk3.x86_64
yum -y install gtk3-devel.x86_64
yum -y install python3-devel.x86_64
# 相关库包
pip3 install python-config
pip install wxPython
pip install robotframework-ride

# GUI支持
export DISPLAY=:0.0
# 开启访问权限
xhost +

# 测试浏览器截屏
yum -y install google-chrome-stable
yum install firefox
chromedriver geckodriver 驱动放在/usr/local/bin/并授权
firefox --screenshot test.png http://www.baidu.com
阅读全文
测试理论

测试人员在软件开发过程中的任务

1、尽可能早的找出系统中的Bug;
2、避免软件开发过程中缺陷的出现;
3、衡量软件的品质,保证系统的质量;
4、关注用户的需求,并保证系统符合用户需求。
总的目标是:确保软件的质量。

完整的测试组成阶段

可行性分析、需求分析、概要设计、详细设计、编码、单元测试、集成测试、系统测试、验收测试

软件测试类型

按测试策略分类:1、静态与动态测试2、黑盒与白盒测试 3、手工和自动测试 4、冒烟测试 5、回归测试;

按测试阶段分类:单元测试、集成测试、系统测试;

其他常见测试方法:1、功能测试 2、性能测试 3、压力测试 4、负载测试 5、易用性测试 6、安装测试 7、界面测试 8、配置测试 9、文档测试 10、兼容性测试 11、安全性测试 12、恢复测试

黑盒测试

一般用来确认软件功能的正确性和可操作性,目的是检测软件的各个功能是否能得以实现,把被测试的程序当作一个黑盒,不考虑其内部结构,在知道该程序的输入和输出之间的关系或程序功能的情况下,依靠软件规格说明书来确定测试用例和推断测试结果的正确性。

优点:比较简单,不需要了解程序内部的代码及实现;与软件的内部实现无关; 从用户角度出发,能很容易的知道用户会用到哪些功能,会遇到哪些问题;基于软件开发文档,所以也能知道软件实现了文档中的哪些功能;在做软件自动化测试时较为方便。

缺点:不可能覆盖所有的代码,覆盖率较低,大概只能达到总代码量的30%;自动化测试的复用性较低。

黑盒测试的测试用例常见设计方法

1)等价类划分: 等价类是指某个输入域的子集合.在该子集合中,各个输入数据对于揭露程序中的错误都是等效的.并合理地假定:测试某等价类的代表值就等于对这一类其它值的测试.因此,可以把全部输入数据合理划分为若干等价类,在每一个等价类中取一个数据作为测试的输入条件,就可以用少量代表性的测试数据.取得较好的测试结果.等价类划分可有两种不同的情况:有效等价类和无效等价类.

2)边界值分析法:是对等价类划分方法的补充。测试工作经验告诉我,大量的错误是发生在输入或输出范围的边界上,而不是发生在输入输出范围的内部.因此针对各种边界情况设计测试用例,可以查出更多的错误.

使用边界值分析方法设计测试用例,首先应确定边界情况.通常输入和输出等价类的边界,就是应着重测试的边界情况.应当选取正好等于,刚刚大于或刚刚小于边界的值作为测试数据,而不是选取等价类中的典型值或任意值作为测试数据.

3)错误猜测法:基于经验和直觉推测程序中所有可能存在的各种错误, 从而有针对性的设计测试用例的方法.

错误推测方法的基本思想: 列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据他们选择测试用例. 例如, 在单元测试时曾列出的许多在模块中常见的错误. 以前产品测试中曾经发现的错误等, 这些就是经验的总结. 还有, 输入数据和输出数据为0的情况. 输入表格为空格或输入表格只有一行. 这些都是容易发生错误的情况. 可选择这些情况下的例子作为测试用例.

4)因果图方法:前面介绍的等价类划分方法和边界值分析方法,都是着重考虑输入条件,但未考虑输入条件之间的联系, 相互组合等. 考虑输入条件之间的相互组合,可能会产生一些新的情况. 但要检查输入条件的组合不是一件容易的事情, 即使把所有输入条件划分成等价类,他们之间的组合情况也相当多. 因此必须考虑采用一种适合于描述对于多种条件的组合,相应产生多个动作的形式来考虑设计测试用例. 这就需要利用因果图(逻辑模型). 因果图方法最终生成的就是判定表. 它适合于检查程序输入条件的各种组合情况.

5)正交表分析法:可能因为大量的参数的组合而引起测试用例数量上的激增,同时,这些测试用例并没有明显的优先级上的差距,而测试人员又无法完成这么多数量的测试,就可以通过正交表来进行缩减一些用例,从而达到尽量少的用例覆盖尽量大的范围的可能性。

6)场景分析方法:指根据用户场景来模拟用户的操作步骤,这个比较类似因果图,但是可能执行的深度和可行性更好。

7)状态图法:通过输入条件和系统需求说明得到被测系统的所有状态,通过输入条件和状态得出输出条件;通过输入条件、输出条件和状态得出被测系统的测试用例。

8)大纲法:大纲法是一种着眼于需求的方法,为了列出各种测试条件,就将需求转换为大纲的形式。大纲表示为树状结构,在根和每个叶子结点之间存在唯一的路径。大纲中的每条路径定义了一个特定的输入条件集合,用于定义测试用例。树中叶子的数目或大纲中的路径给出了测试所有功能所需测试用例的大致数量。

白盒测试

根据软件内部的逻辑结构分析来进行测试,是基于代码的测试,测试人员通过阅读程序代码或者通过使用开发工具中的单步调试来判断软件的质量,一般白盒测试由项目经理在程序员开发中来实现。

优点:帮助软件测试人员增大代码的覆盖率,提高代码的质量,发现代码中隐 藏的问题。

缺点:程序运行会有很多不同的路径,不可能测试所有的运行路径;测试基于代码,只能测试开发人员做的对不对,而不能知道设计的正确与否,可能会漏掉一些功能需求;系统庞大时,测试开销会非常大。

静态测试是不运行程序本身而寻找程序代码中可能存在的错误或评估程序代码的过程。

动态测试是实际运行被测程序,输入相应的测试实例,检查运行结果与预期结果的差异,判定执行结果是否符合要求,从而检验程序的正确性、可靠性和有效性,并分析系统运行效率和健壮性等性能。

α测试是由一个用户在开发环境下进行的测试,也可以是公司内部的用户在模拟实际操作环境下进行的受控测试,Alpha测试不能由程序员或测试员完成。

β测试是软件的多个用户在一个或多个用户的实际使用环境下进行的测试。开发者通常不在测试现场,Beta测试不能由程序员或测试员完成。

单元测试:单元测试是针对软件设计的最小单位––程序模块甚至代码段进行正确性检验的测试工作,通常由开发人员进行。

集成测试:集成测试是将模块按照设计要求组装起来进行测试,主要目的是发现与接口有关的问题。由于在产品提交到测试部门前,产品开发小组都要进行联合调试,因此在大部分企业中集成测试是由开发人员来完成的。

系统测试:系统测试是在集成测试通过后进行的,目的是充分运行系统,验证各子系统是否都能正常工作并完成设计的要求。它主要由测试部门进行,是测试部门最大最重要的一个测试,对产品的质量有重大的影响。

验收测试:验收测试以需求阶段的《需求规格说明书》为验收标准,测试时要求模拟实际用户的运行环境。对于实际项目可以和客户共同进行,对于产品来说就是最后一次的系统测试。测试内容为对功能模块的全面测试,尤其要进行文档测试。

单元测试的覆盖率

代码覆盖率也被⽤于自动化测试和⼿手测试,来度量测试是否全面的指标之⼀,应用覆盖率的思想增强测试用例的设计

1
2
3
4
5
6
7
# 被测试函数
def demo_method(a, b, x):
if (a > 1 and b == 0):
x= x/a
if (a == 2 or x > 1):
x = x+1
return x

image-20200917224230788

Statement Coverage

语句覆盖:运行测试用例的过程被击中的代码行即称为被覆盖的语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
• 测试用例:
• a=3, b=0,x=3
• 漏洞:
• and -> or
# 判断覆盖(Decision Coverage)定义:
# 运行测试用例的过程被击中的判定语句
• 测试用例:
TestCases a b x (a>1)&&(b==0) a==2||x>1 ExecutePath
Case1 2 0 3 T T 135
Case2 1 0 1 F F 124
Case3 3 0 3 T F 134
Case4 2 1 1 F T 125
• 漏洞:
• a==2 or x>1 ->a==2 or x<1

Condition Coverage

条件覆盖:每一个判断覆盖语句中,每个可能的子条件或者合并条件都覆盖到

1
2
3
4
5
6
7
8
• 测试用例:if (a > 1 and b == 0)
TestCases a>1 b==0
Case1 T T
Case2 T F
Case3 F T
Case4 F F
• 缺陷:
• 测试用例指数级增加(2**conditions)

Path Coverage

路径覆盖:每一个可能的路径都覆盖

1
2
3
4
5
6
• 测试用例:
TestCases a b x ExecutePath
Case1 2 0 3 135
Case2 1 0 1 124
Case3 3 0 3 134
Case4 2 1 1 125
阅读全文
corn表达式

对应字段的表示(从左到右)

1
2
3
4
5
6
7
1. Seconds
2. Minutes
3. Hours
4. Day-of-Month
5. Month
6. Day-of-Week
7. Year (可选字段)

字段取值范围与表示

字段名 允许的值 允许的特殊字符
0-59 , - * /
0-59 , - * /
小时 0-23 , - * /
1-31 , - * ? / L W C
1-12 or JAN-DEC , - * /
周几 1-7 or SUN-SAT , - * ? / L C #
年 (可选字段) empty, 1970-2099 , - * /
1
2
3
4
5
6
7
“?”字符:表示不确定的值
“,”字符:指定数个值
“-”字符:指定一个值的范围
“/”字符:指定一个值的增加幅度。n/m表示从n开始,每次增加m
“L”字符:用在日表示一个月中的最后一天,用在周表示该月最后一个星期X
“W”字符:指定离给定日期最近的工作日(周一到周五)
“#”字符:表示该月第几个周X。6#3表示该月第3个周五

Cron表达式举例:

1
2
3
4
5
6
7
8
每隔5秒执行一次:*/5 * * * * ?
每隔5分钟执行一次:0 */5 * * * ?常用
每天6点执行一次:0 0 6 * * ?
每月1号凌晨6点执行一次:0 0 6 1 * ?
每月最后一天23点执行一次:0 0 23 L * ?
每周星期天凌晨1点实行一次:0 0 1 ? * L
在26分、29分、33分执行一次:0 26,29,33 * * * ?
每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ?常用
阅读全文
postman使用

Content-Type

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Content-Type
Content-Type用于指定内容类型,一般是指网页中存在的Content-Type, Content-Type属性指定请求和响应的HTTP内容类型。如果未指定ContentType,默认为text/html
1、application/x-www-form-urlencoded是常用的表单发包方式,普通的表单提交,或者js发包,默认都是通过这种方式。
2、multipart/form-data用在发送文件的POST包。
还有boundary用于分割数据。当文件太长,HTTP无法在一个包之内发送完毕,就需要分割数据,分割成一个一个chunk发送给服务端,那么一用于区分数据块,而后面16进制串就是标示区分包作用。
# 常见的Content-Type:
1.text/html
2.text/plain
3.text/css
4.text/javascript
5.application/x-wwwx-form-urlencoded
6.multipart/form-data
7.application/ison
8.application/xml

断言

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
access_ token接口将返回token放到变量中,并加断言
pm. test("响应状态码是200"function () {
pm. response . to. have . status(200);
});
pm. test("包含accesstoken"function () {
pm. expect(pm. response . text()) . to. include("access_ .token");
});
pm. test("响应小于500ms"function () {
pm. expect(pm. response . responseTime). to . be . below(500);
});
//将数据解析为json格式
var data = JSON. parse(responseBody);
//获取access_ .token的值
var access_ token = data. access_ token;
//把这个变量保存到环境变量中,这样大家都能用了
pm. envi ronment . set(" access_ .token" ,access_ token);
pm. test("过期时间为7200"function () {
var jsonData = pm. response . json();
pm. expect(jsonData. expires. _in) . to . eq1(7200);
});
阅读全文
用例设计相关要点

用例设计原则

功能划分要简单清晰,一个测试用例只检查一个功能模块
测试用例的划分也要单一,一个测试用例只检查功能点的一种情况
测试用例要有简单的目的描述,要有明确的执行前提,包括环境,场景,数据,要有明确的测试数据
一般设计步骤
根据设计规格得出基本测试用例
1.补充边界值测试用例
2.补充错误猜测测试用例
3.补充异常测试用例
4.补充性能测试用例

接口

概述

是测试系统组件间接口的一种测试。
接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。
测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。
测试沟通能力

接口逻辑的正确性

输入不同正确组合,验证返回正确(不同的响应状态码),逻辑正确,精度正确。

接口的关联性

依赖有无,正确,其他,时间

接口的异常健壮性

空,不符合需求,功能不符合(参数个数,类型,缺失,左右边界,上下溢出,优先级,逻辑,文件各种问题)

接口的安全性

输入的内容对域,对访问控制,权限,数据库sql注入

黑盒测试

把软件看成一个黑盒子,不考虑内部结构,只考虑输入和输出,测试功能和ui界面。

等价类划分法

将无限的测试变成有限的测试
大多用于输入框中的测试

有效等价类: 一条用例尽量覆盖有效规则
无效等价类:一条用例只能出现一次无效规则
适用对象:输入框,页面上的多个输入框不存在逻辑关系
缺点:没有关注到边界的问题,没有关注到输入框的逻辑关系

边界值分析法

在任何用例中都必须用到的方法

边界值 :上点 离点 内点 一般配合等价类使用

错误值推测法

能帮助我们在原有用例的基础上追加补充一些用例

因果图法和判定表法

输入条件需要考虑组合情况
参数之间存在逻辑关系,不同逻辑组合会输出不同结果 参数之间存在约束关系,输出结果不确定

判定表: 多条输入 多条输出 输入和输出之间存在逻辑关系

具体做法:条件桩 条件的组合(二进制)动作桩 动作项 适当的项目合并(注意不要合并成漏项)

正交试验法

参数配置类的测试

多个选项,都是正值,没有逻辑关系,因子的值两两相交一次(两个因子的值在一个用例中出现一次)利用正交工具

场景法

业务流程清晰的系统
基本流和备选流,一般基本流为正常的测试。测试结果为成功的测试,备选流为异常的情况测试

功能图法

对于有状态迁移和逻辑功能路径组合的情况

对照程序逻辑,检查已设计出的测试用例逻辑覆盖度,如果没有达到要求的覆盖标准,应再补充足够的测试用例。

白盒测试

测试程序的内部结构和接口
语句覆盖,判定覆盖,条件覆盖,判定条件覆盖,条件组合覆盖,路径覆盖

阅读全文
SVN命令的使用和功能详解

命令的使用

1、检出

1
2
3
4
5
6
7
8
9
10
11
svn co http://路径(目录或文件的全路径) [本地目录全路径]  --username 用户名 --password 密码
svn co svn://路径(目录或文件的全路径) [本地目录全路径] --username用户名 --password 密码
svn checkout http://路径(目录或文件的全路径) [本地目录全路径] --username 用户名
svn checkout svn://路径(目录或文件的全路径) [本地目录全路径] --username 用户名
# 如果不带--password 参数传输密码的话,会提示输入密码,建议不要用明文的--password 选项。
# 其中 username 与 password前是两个短线,不是一个。
# 不指定本地目录全路径,则检出到当前目录下。
svn cosvn://localhost/测试工具 /home/testtools --username wzhnsc
svn co http://localhost/test/testapp--username wzhnsc
svn checkout svn://localhost/测试工具/home/testtools--username wzhnsc
svn checkouthttp://localhost/test/testapp--username wzhnsc***\*

2、导出(导出不带.svn文件夹的目录树)

1
2
3
4
5
6
7
8
9
10
11
12
13
svn export [-r 版本号] http://路径(目录或文件的全路径) [本地目录全路径] --username 用户名
svn export [-r 版本号] svn://路径(目录或文件的全路径) [本地目录全路径] --username 用户名
svn export 本地检出的(即带有.svn文件夹的)目录全路径 要导出的本地目录全路径
# 第一种从版本库导出干净工作目录树的形式是指定URL,
#如果指定了修订版本号,会导出相应的版本,
#如果没有指定修订版本,则会导出最新的,导出到指定位置。
#如果省略 本地目录全路径,URL的最后一部分会作为本地目录的名字。
# 第二种形式是指定 本地检出的目录全路径 到要导出的本地目录全路径,所有的本地修改将会保留,
#但是不在版本控制下(即没提交的新文件,因为.svn文件夹里没有与之相关的信息记录)的文件不会拷贝。
# example:
svn export svn://localhost/测试工具/home/testtools --usernamewzhnsc
svn export svn://localhost/test/testapp--usernamewzhnsc
svn export /home/testapp/home/testtools

3、添加新文件

1
2
3
4
5
6
svn add 文件名
# 注:告诉SVN服务器要添加文件了,还要用svn commint -m真实的上传上去!
svn add test.php #添加test.php
svn commit -m “添加我的测试用test.php“ test.php
svn add *.php #添加当前目录下所有的php文件
svn commit -m “添加我的测试用全部php文件“ *.php

4、提交

1
2
3
4
5
6
7
8
9
10
svn commit -m “提交备注信息文本“ [-N] [--no-unlock] 文件名
svn ci -m “提交备注信息文本“ [-N] [--no-unlock] 文件名
#必须带上-m参数,参数可以为空,但是必须写上-m
# example:
svn commit -m “提交当前目录下的全部在版本控制下的文件“ * # 注意这个*表示全部文件
svn commit -m “提交我的测试用test.php“ test.php
svn commit -m “提交我的测试用test.php“ -N --no-unlock test.php # 保持锁就用–no-unlock开关
svn ci -m “提交当前目录下的全部在版本控制下的文件“ * # 注意这个*表示全部文件
svn ci -m “提交我的测试用test.php“ test.php
svn ci -m “提交我的测试用test.php“ -N --no-unlock test.php # 保持锁就用–no-unlock开关

5、更新文件

1
2
3
4
5
6
7
svn update
svn update -r 修正版本 文件名
svn update 文件名
# example:
svn update # 后面没有目录,默认将当前目录以及子目录下的所有文件都更新到最新版本
svn update -r 200 test.cpp # 将版本库中的文件 test.cpp还原到修正版本(revision)200
svnupdate test.php # 更新与版本库同步。提交的时候提示过期冲突,需要先 update 修改文件,然后清除svn resolved,最后再提交commit。

6、删除文件

1
2
3
4
5
6
7
8
9
svn delete svn://路径(目录或文件的全路径) -m “删除备注信息文本”
# 推荐如下操作:
svn delete 文件名
svn ci -m “删除备注信息文本”
# example:
svn deletesvn://localhost/testapp/test.php -m “删除测试文件test.php”
# 推荐如下操作:
svn delete test.php
svn ci -m “删除测试文件test.php”

7、加锁/解锁

1
2
3
4
5
svn lock -m “加锁备注信息文本“ [--force] 文件名 
svn unlock 文件名
# example:
svn lock -m “锁信测试用test.php文件“ test.php
svn unlock test.php

8、比较差异

1
2
3
4
5
svn diff 文件名 
svn diff -r 修正版本号m:修正版本号n 文件名
# example:
svn diff test.php # 将修改的文件与基础版本比较
svn diff -r 200:201 test.php # 对修正版本号200 和 修正版本号201 比较差异

9、查看文件或者目录状态

1
2
3
4
5
svn st 目录路径/名
svn status 目录路径/名# 目录下的文件和子目录的状态,正常状态不显示 【?:不在svn的控制中; M:内容被修改;C:发生冲突;A:预定加入到版本库;K:被锁定】
svn -v 目录路径/名
svn status -v 目录路径/名# 显示文件和子目录状态【第一列保持相同,第二列显示工作版本号,第三和第四列显示最后一次修改的版本号和修改人】
#svn status、svn diff和 svn revert这三条命令在没有网络的情况下也可以执行的,原因是svn在本地的.svn中保留了本地版本的原始拷贝。

10、查看日志

1
2
3
svn log 文件名
# example:
svn log test.php # 显示这个文件的所有修改记录,及其版本号的变化

11、查看文件详细信息

1
2
3
svn info 文件名
# example:
svn info test.php

12、SVN 帮助

1
2
svn help # 全部功能选项
svn help ci # 具体功能的说明

13、查看版本库下的文件和目录列表

1
2
3
4
5
svn list svn://路径(目录或文件的全路径)
svn ls svn://路径(目录或文件的全路径)
# example:
svn list svn://localhost/test
svn ls svn://localhost/test# 显示svn://localhost/test目录下的所有属于版本库的文件和目录

14、创建纳入版本控制下的新目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
svn mkdir 目录名
svn mkdir -m "新增目录备注文本" http://目录全路径
# example:
svn mkdir newdir
svn mkdir -m "Making a new dir."svn://localhost/test/newdir
#添加完子目录后,一定要回到根目录更新一下,不然在该目录下提交文件会提示“提交失败”
svn update
#如果手工在checkout出来的目录里创建了一个新文件夹newsubdir,再用svn mkdir newsubdir命令后,SVN会提示:
#  svn: 尝试用 “svn add”或 “svn add --non-recursive”代替?
#  svn: 无法创建目录“hello”: 文件已经存在
#此时,用如下命令解决:
  svn add --non-recursivenewsubdir
#在进入这个newsubdir文件夹,用ls -a查看它下面的全部目录与文件,会发现多了:.svn目录
  再用 svn mkdir -m "添hello功能模块文件"svn://localhost/test/newdir/newsubdir 命令,
#SVN提示:
#  svn: File already exists: filesystem '/data/svnroot/test/db',transaction '4541-1',
#  path '/newdir/newsubdir '

15、恢复本地修改

1
2
3
4
5
svn revert [--recursive] 文件名
#本子命令不会存取网络,并且会解除冲突的状况。但是它不会恢复被删除的目录。
# example:
svn revert foo.c # 丢弃对一个文件的修改
svn revert --recursive . # 恢复一整个目录的文件,.为当前目录

16、把工作拷贝更新到别的URL

1
2
3
svn switch http://目录全路径 本地目录全路径
# example:
svn switch http://localhost/test/456 .# (原为123的分支)当前所在目录分支到localhost/test/456

17、解决冲突

1
2
3
4
5
6
7
8
9
10
11
12
13
svn resolved [本地目录全路径]
# example:
$ svn update
C foo.c
Updated to revision 31.
# 如果你在更新时得到冲突,你的工作拷贝会产生三个新的文件:
$ ls
foo.c
foo.c.mine
foo.c.r30
foo.c.r31
#当你解决了foo.c的冲突,并且准备提交,运行svn resolved让你的工作拷贝知道你已经完成了所有事情。
#你可以仅仅删除冲突的文件并且提交,但是svnresolved除了删除冲突文件,还修正了一些记录在工作拷贝管理区域的记录数据,所以推荐使用这个命令。

18、不checkout而查看输出特定文件或URL的内容

1
2
3
svn cat http://文件全路径
# example:
svn cat http://localhost/test/readme.txt

19、新建一个分支copy

1
svn copy branchAbranchB -m "make B branch" #从branchA拷贝出一个新分支branchB

20、合并内容到分支merge

1
svn merge branchAbranchB # 把对branchA的修改合并到分支branchB

TortoiseSVN

TortoiseSVN是windows下其中一个非常优秀的SVN客户端工具。通过使用它,我们可以可视化的管理我们的版本库。不过由于它只是一个客户端,所以它不能对版本库进行权限管理。

TortoiseSVN每个菜单项解释

01、SVN Checkout(SVN取出)

点击SVN Checkout,弹出检出提示框,在URL of repository输入框中输入服务器仓库地址,在Checkout directory输入框中输入本地工作拷贝的路径,点击确定,即可检出服务器上的配置库。

02、SVN Update(SVN更新)

如果配置库在本地已有工作拷贝,则取得最新版本只是执行SVN Update即可,点击SVN Update,系统弹出更新提示框,点击确定,则把服务器是最新版本更新下来

03、Import(导入)

选择要提交到服务器的目录,右键选择TortoiseSVN—-Import,系统弹出导入提示框,在URL of repository输入框中输入服务器仓库地址,在Import Message输入框中输入导入日志信息,点击确定,则文件导入到服务器仓库中。

04、Add(加入)

如果有多个文件及文件夹要提交到服务器,我们可以先把这些要提交的文件加入到提交列表中,要执行提交操作,一次性把所有文件提交,如图,可以选择要提交的文件,然后点击执行提交(SVN Commit),即可把所有文件一次性提交到服务器上

05、Resolving Conflicts(解决冲突)

有时你从档案库更新文件会有冲突。冲突产生于两人都修改文件的某一部分。解决冲突只能靠人而不是机器。当产生冲突时,你应该打开冲突的文件,查找以<<<<<<<开始的行。冲突部分被标记:
<<<<<<< filename

your changes

code merged from repository
>>>>>>> revision
Subversion为每个冲突文件产生三个附加文件:
filename.ext.mine
更新前的本地文件。
filename.ext.rOLDREV
你作改动的基础版本。
filename.ext.rNEWREV
更新时从档案库得到的最新版本。
使用快捷菜单的编辑冲突Edit Conflict命令来解决冲突。然后从快捷菜单中执行已解决Resolved命令,将改动送交到档案库。请注意,解决命令并不解决冲突,而仅仅是删除filename.ext.mineandfilename.ext.r*文件并允许你送交。

06、Check for Modifications(检查更新)

点击Check for Modifications,系统列表所以待更新的文件及文件夹的状态.

07、Revision Graph(版本分支图)

查看文件的分支,版本结构,可以点击Revision Graph,系统以图形化形式显示版本分支.

08、Rename(改名)

SVN支持文件改名,点击Rename,弹出文件名称输入框,输入新的文件名称,点击确定,再把修改提交,即可完成文件改名

09、Delete(删除)

SVN支持文件删除,而且操作简单,方便,选择要删除的文件,点击Delete,再把删除操作提交到服务器

10、Moving(移动)

选择待移动的文件和文件夹;按住右键拖动right-drag文件(夹)到跟踪拷贝内的新地方;松开左键;在弹出菜单中选择move files in Subversion to here

11、Revert(还原)

还原操作,如刚才对文件做了删除操作,现在把它还原回来,点击删除后,再点击提交,会出现如上的提示框,点击删除后,再点击Revert,即已撤销删除操作,如果这时候点击提交,则系统弹出提示框:没有文件被修改或增加,不能提交

12、Branch/Tag(分支/标记)

当需要创建分支,点击Branch/Tag,在弹出的提示框中,输入分支文件名,输入日志信息,点击确定,分支创建成功,然后可查看文件的版本分支情况

13、Switch(切换)

文件创建分支后,你可以选择在主干工作,还是在分支工作,这时候你可以通过Switch来切换。

14、Merge(合并)

主干和分支的版本进行合并,在源和目的各输入文件的路径,版本号,点击确定。系统即对文件进行合并,如果存在冲突,请参考冲突解决。

15、Export(导出)

把整个工作拷贝导出到本地目录下,导出的文件将不带svn文件标志,文件及文件夹没有绿色的”√”符号标志。

16、Relocate(重新定位)

当服务器上的文件库目录已经改变,我们可以把工作拷贝重新定位,在To URL输入框中输入新的地址

17、Add to Ignore List(添加到忽略列表)

大多数项目会有一些文件(夹)不需要版本控制,如编译产生的*.obj, *.lst,等。每次送交,TortoiseSVN提示那些文件不需要控制,挺烦的。这时候可以把这些文件加入忽略列表。

18、SVN其它相关功能

客户端修改用户密码:打开浏览器,在地址栏内输入http://192.168.1.250/cgi-bin/ChangePasswd,启动客户端修改用户密码的界面,输入正确的用户名,旧密码,新密码(注意密码的位数应该不小于6,尽量使用安全的密码),点击修改即可.

19、SVN Commit(版本提交)

把自己工作拷贝所做的修改提交到版本库中,这样别人在获取最新版本(Update)的时候就可以看到你的修改了。

20、Show log(显示日志)

显示当前文件(夹)的所有修改历史。SVN支持文件以及文件夹独立的版本追溯。

21、Repo-Browser(查看当前版本库)

查看当前版本库,这是TortoiseSVN查看版本库的入口,通过这个菜单项,我们就可以进入配置库的资源管理器,然后就可以对配置库的文件夹进行各种管理,相当于我们打开我的电脑进行文件管理一样。

22、Revision Graph(版本图形)

查看当前项目或文件的修订历史图示。如果项目比较大型的话,一般会建多个分支,并且多个里程碑(稳定版本发布),通过这里,我们就可以看到项目的全貌。

23、Resolved(解决冲突)

如果当前工作拷贝和版本库上的有冲突,不能自动合并到一起,那么当你提交修改的时候,tortoisesvn就会提示你存在冲突,这时候你就可以通过这个菜单项来解决冲突。冲突的解决有两种,一种是保留某一份拷贝,例如使用配置库覆盖当前工作拷贝,或者反过来。还有一种是手动解决冲突,对于文本文件,可以使用tortoiseSVN自带的工具,它会列出存在冲突的地方,然后你就可以和提交者讨论怎么解决这个冲突。同时它也对Word有很好的支持

24、Update to Revision(更新至版本)

从版本库中获取某一个历史版本。这个功能主要是方便查看历史版本用,而不是回滚版本。注意:获取下来之后,对这个文件不建议进行任何操作。如果你做了修改,那么当你提交的时候SVN会提示你,当前版本已失效(即不是最新版本),无法提交,需要先update一下。这样你所做的修改也就白费了。

25、Revert(回滚)

如果你对工作拷贝做了一些修改,但是你又不想要了,那么你可以使用这个选项把所做的修改撤销

26、Cleanup(清除状态)

如果当前工作拷贝有任何问题的话,可以使用这个选项进行修正。例如,有些文件原来是版本控制的,但是你没有通过tortoiseSVN就直接删除了,但是tortoiseSVN还是保留着原来的信息(每个文件夹下都有一个.svn的隐藏文件夹,存放着当前文件夹下所有文件夹的版本信息)所以这就会产生一些冲突。可以使用cleanup来清理一下。

27、GetLock/ReleaseLock(加锁/解锁)

如果你不想别人修改某个文件的话,那么你就可以把这个文件进行加锁,这样可以保证只有你对这个文件有修改权。除非你释放了锁,否则别人不可能提交任何修改到配置库中

28、Branch/tag(分支/标签)

Branch是分支的意思。例如当在设计一个东西的时候,不同的人有不同的实现,但是没有经过实践检验,谁也不想直接覆盖掉其他人的设计,所以可以引出不同的分支。将来如果需要,可以将这些分支进行合并。
tag是打标签的意思。通常当项目开发到一定程度,已经可以稳定运行的时候,可以对其打上一个标签,作为稳定版。将来可以方便的找到某个特定的版本(当然我们也可以使用版本号来查找,但是数字毕竟不方便)
SVN对于分支和标签都是采用类似Linux下硬链接的方式(同一个文件可以存在两个地方,删除一个不会影响另一个,所做修改会影响另一个),来管理文件的,而不是简单的复制一份文件的拷贝,所以不会有浪费存储空间的问题存在。

29、Export(导出)

这个功能是方便我们部署用。当我们需要发布一个稳定版本时,就可以使用这个功能将整个工程导出到某个文件夹,新的文件夹将不会包含任何版本信息了。

30、Relocate(版本库转移)

当我们版本库发生转移的时候就需要用到这个功能了。例如我原先的版本库是建在U盘上的,现在转移到(复制整个配置库文件夹)开发服务器上,使用https代替文件系统的访问。因此就需要将原来的工作拷贝的目标版本库重新定位到开发服务器上。

31、create patch(创建补丁)

创建补丁。如果管理员不想让任何人都随便提交修改,而是都要经过审核才能做出修改,那么其他人就可以通过创建补丁的方式,把修改信息(补丁文件)发送给管理员,管理员审核通过之后就可以使用apply patch提交这次修改了。

阅读全文
vmware

VMware网络配置

VMware三种网络模式简介

VMWare提供了三种工作模式,它们是bridged(桥接模式)、NAT(网络地址转换模式)和host-only(主机模式)。安装好虚拟机以后,在网络连接里面可以看到多了两块网卡。如下图

bridged(桥接模式)
1
2
3
4
5
在这种模式下,VMWare虚拟出来的操作系统就像是局域网中的一台独立的主机,它可以访问网内任何一台机器。
在桥接模式下,你需要手工为虚拟系统配置IP地址、子网掩码,而且还要和宿主机器处于同一网段,这样虚拟系统才能和宿主机器进行通信。同时,由 于这个虚拟系统是局域网中的一个独立的主机系统,那么就可以手工配置它的TCP/IP配置信息,以实现通过局域网的网关或路由器访问互联网。
使用桥接模式的虚拟系统和宿主机器的关系,就像连接在同一个Hub上的两台电脑。想让它们相互通讯,你就需要为虚拟系统配置IP地址和子网掩码,否则就无法通信。
1)如果你想利用VMWare在局域网内新建一个虚拟服务器,为局域网用户提供网络服务,就应该选择桥接模式。
2)如果你有路由器的话,那么就可以使用桥接方式上网,因为此时你申请的IP地址是写在了路由器上,而不是你的机器上,这样包括你的主机,虚拟机,也包括 连在路由器上的其他人的机器,都将可以上网,使用着由路由器分配的IP地址。

架构图:

使用VMnet0虚拟交换机,此时虚拟机相当与网络上的一台独立计算机与主机一样,拥有一个独立的IP地址。使用桥接方式,A,A1,A2,B可互访

虚拟机就像一台真正的计算机一样,直接连接到实际的网络上,可以理解为与宿主机没有任何联系。

host-only(主机模式)
1
2
3
4
在某些特殊的网络调试环境中,要求将真实环境和虚拟环境隔离开,这时你就可采用host-only模式。在host-only模式中,所有的虚拟系统是可以相互通信的,但虚拟系统和真实的网络是被隔离开的。
提示:在host-only模式下,虚拟系统和宿主机器系统是可以相互通信的,相当于这两台机器通过双绞线互连。
在host-only模式下,虚拟系统的TCP/IP配置信息(如IP地址、网关地址、DNS服务器等),都是由VMnet1(host-only)虚拟网络的DHCP服务器来动态分配的。
如果你想利用VMWare创建一个与网内其他机器相隔离的虚拟系统,进行某些特殊的网络调试工作,可以选择host-only模式。

架构图:

使用Vmnet1虚拟交换机,此时虚拟机只能与虚拟机、主机互访。也就是不能上Internet。使用Host方式,A,A1,A2可以互访,但A1,A2不能访问B,也不能被B访问。

这种方式下,虚拟机的网卡连接到宿主的 VMnet1 上,但系统并不为虚拟机提供任何路由服务,因此虚拟机只能和宿主机进行通信,而不能连接到实际网络上。

NAT(网络地址转换模式)
1
2
使用NAT模式,就是让虚拟系统借助NAT(网络地址转换)功能,通过宿主机器所在的网络来访问公网。也就是说,使用NAT模式可以实现在虚拟 系统里访问互联网。NAT模式下的虚拟系统的TCP/IP配置信息是由VMnet8(NAT)虚拟网络的DHCP服务器提供的,无法进行手工修改,因此虚 拟系统也就无法和本局域网中的其他真实主机进行通讯。采用NAT模式最大的优势是虚拟系统接入互联网非常简单,你不需要进行任何其他的配置,只需要宿主机 器能访问互联网即可。
如果你想利用VMWare安装一个新的虚拟系统,在虚拟系统中不用进行任何手工配置就能直接访问互联网,建议你采用NAT模式。

架构图:

使用Vmnet8虚拟交换机,此时虚拟机可以通过主机单向网络上的其他工作站,其他工作站不能访问虚拟机。用NAT方式,A1,A2可以访问B,但B不可以访问A1,A2。但A,A1,A2可以互访。

这种方式下,虚拟机的网卡连接到宿主的 VMnet8 上。此时系统的 VMWare NAT Service 服务就充当了路由器的作用,负责将虚拟机发到 VMnet8 的包进行地址转换之后发到实际的网络上,再将实际网络上返回的包进行地址转换后通过 VMnet8 发送给虚拟机。VMWare DHCP Service 负责为虚拟机提供 DHCP 服务。

VMware虚拟机跨主机复制

vmx文件是虚拟机系统的配置文件,记录虚拟机的配置的,如内存、硬盘。
vmdk则是虚拟磁盘文件。
复制对应Virtual Machines的.vmx文件和所有的.vmdk文件到新电脑,VMware Workstation中打开虚拟机,选择.vmx文件即可

question

ssh远程MacOS时 ssh connect refused

原因:

ssh服务未开启/苹果的安全限制

解决:

开启服务
sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist
查看ssh服务是否开启
sudo launchctl list |grep ssh
苹果的安全限制
sudo systemsetup -f -setremotelogin on

阅读全文
python基础

版本共存

手工配置

在安装Python3(>=3.3)时,Python的安装包实际上在系统中安装了一个启动器py.exe,默认放置在文件夹C:\Windows\下面。这个启动器允许我们指定使用Python2还是Python3来运行代码(当然前提是你已经成功安装了Python2和Python3)。
运行代码:

1
2
py -2 hello.py    #python2
py -3 hello.py #python3

如果你觉得参数 -2/-3 麻烦,由于 py.exe 这个启动器允许你在代码里面加入说明,指示这个文件是用python2还是3版本运行,可以在代码文件最前面加入一行说明
python2版本(编码说明可以放在第二行)

1
2
#!python2
#coding:gbk12

python3版本

1
#!python3

这样就可以直接运行

1
py hello.py  #将自动转入相应版本1

当2和3同时存在Windows上时,他们对应的pip都叫pip.exe,所以不能直接使用 pip install 命令安装软件包,而是依靠py.exe来指定pip版本。

1
2
py -2 -m pip install *****  #python2
py -3 -m pip install ***** #python3
  • 系统优先级

按照环境变量的前后,如以 python 2 为 优先:

设置环境变量PATH为:

1
C:\Python27;C:\Python27\Scripts;C:\Python36\Scripts\;C:\Python36\;

Pyenv

pyenv是一个forked自ruby社区的简单、低调、遵循UNIX哲学的Python环境管理工具,用于安装和管理多个Python版本。它使开发人员能够快速访问更新版本的Python,并保持系统干净,避免不必要的包膨胀。它还提供了从 Python 的一个版本快速切换到另一个版本的能力,以及指定给定项目使用的Python版本并可以自动切换到该版本, 同时结合vitualenv插件可以方便的管理对应的包源
github:
https://github.com/pyenv/pyenv
https://github.com/pyenv-win/pyenv-win

linux
  • 安装依赖

    1
    apt install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python-openssl git
  • clone存储库

    1
    git clone https://github.com/pyenv/pyenv.git ~/.pyenv
  • 配置环境

    1
    2
    3
    4
    5
    6
    # 设置一些重要的环境变量并设置 pyenv 自动完成
    echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
    echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
    echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bashrc
    # 重新启动 shell
    exec "$SHELL"
  • 验证安装

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 列出可用的 Python 版本
    pyenv install --list
    # 安装python版本(Pyenv从源代码构建,时间较长)
    pyenv install 3.8.10
    # 验证Python版本是否已安装
    pyenv versions
    # 将Python的版本更改为 3.8.10并放入 python shell
    pyenv global 3.8.10
    python
  • 命令

    参阅 pyenv help <command>

    • –version :: 显示 pyenv命令的版本列出所有可用的 pyenv 命令
    • exec :: 使用选定的 Python 版本运行可执行文件
    • global :: 设置或显示全局 Python 版本
    • help :: 显示命令的帮助
    • hooks :: 列出给定 pyenv 命令的钩子脚本
    • init :: 配置pyenv的shell环境
    • install :: 使用 python-build 安装 Python 版本
    • local :: 设置或显示本地应用程序特定的 Python 版本
    • prefix :: 显示 Python 版本的前缀
    • rehash :: Rehash pyenv shims(在安装可执行文件后运行)
    • root :: 显示保存版本和垫片的根目录
    • shell :: 设置或显示特定于 shell 的 Python 版本
    • shims:: 列出现有的 pyenv 垫片
    • uninstall:: 卸载特定的 Python 版本
    • version :: 显示当前的 Python 版本及其来源
    • version-file :: 检测设置当前pyenv版本的文件
    • version-name :: 显示当前 Python 版本
    • version-origin ::解释当前 Python 版本是如何设置的
    • versions::列出 pyenv 可用的所有 Python 版本
    • whence ::列出包含给定可执行文件的所有 Python 版本
    • which ::显示可执行文件的完整路径
windows
  • 安装

    1
    choco install pyenv-win
  • 命令

    • commands 列出所有可用的 pyenv 命令
    • local 设置或显示本地应用程序特定的 Python 版本
    • global 设置或显示全局 Python 版本
    • shell 设置或显示特定于 shell 的 Python 版本
    • install 安装 1 个或多个版本的 Python
    • uninstall 卸载 1 个或多个版本的
    • Python Python更新 更新缓存版本 DB
    • rehash Rehash pyenv shims(在切换 Python 版本后运行)
    • vname 显示当前 Python
    • version 显示当前 Python 版本及其原始
    • version-name 显示当前 Python
    • versions 列出 pyenv 可用的所有 Python 版本
    • exec 通过首先准备 PATH 来运行可执行文件,以便选择的 Python
    • which 显示可执行文件的完整路径,
    • whence 列出包含给定可执行文件的所有 Python 版本

包管理

  • 更新
1
pip install --upgrade pip   

镜像源

  • 查看
1
pip config list
  • 设置
1
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
  • 常用源
1
2
3
4
5
6
7
8
9
10
# 阿里云
https://mirrors.aliyun.com/pypi/simple/
# 清华大学
https://pypi.tuna.tsinghua.edu.cn/simple/
# 中国科技大学
https://pypi.mirrors.ustc.edu.cn/simple/
# 中国科学技术大学
https://pypi.mirrors.ustc.edu.cn/simple/
# 豆瓣
https://pypi.douban.com/simple/

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"(py -2/3 -m)pip"
#查看已经安装的第三方库
pip list
# 安装第三方库
pip install 库名
# 查看安装库的详细信息
pip show 库名
# 卸载第三方库
pip uninstall 库名
# 卸载pip
python -m pip uninstall pip
# 检查哪些包需要更新
pip list --outdated
# 升级包
pip install --upgrade SomePackage
centos自带python2.7.5安装pip yum install -y python-pip

安装指定版本

1
2
#只需通过 == 操作符指定
pip install robotframework==2.8.7

问题解决

1
2
3
4
5
6
pip升级format问题:
先确保你在~/.pip 目录下有文件pip.conf
如果没有就创建这个文件:vim ~/.pip/pip.conf
在pip.conf文件里面加入代码:
[list]
format=columns

虚拟环境

确保 Python 已经具备虚拟环境配置库:

1
pip install virtualenv

在某一文件夹下创建虚拟环境:

1
virtualenv venv

虚拟环境生效
使用虚拟环境的二进制目录中的脚本来“激活”该环境。不同平台调用的脚本是不同的(须将 <venv> 替换为包含虚拟环境的目录路径)

平台 Shell 用于激活虚拟环境的命令
POSIX bash/zsh/git-bash $ source /bin/activate
fish $ source /bin/activate.fish
csh/tcsh $ source /bin/activate.csh
PowerShell Core $ /bin/Activate.ps1
Windows cmd.exe C:> \Scripts\activate.bat
PowerShell PS C:> \Scripts\Activate.ps1

命名规范

1
2
3
4
5
6
7
8
9
10
1. 变量命名总结:
- 单下划线开头变量:protected
- 双下划线开头变量:private
- 双下划线开头,双下划线结尾:系统内置变量
2. 函数命名总结:
- 私有方法:小写和一个前导下划线
- 特殊方法(魔术方法):小写和两个前导下划线,两个后置下划线
- 函数参数:小写和下划线,缺省值等号两边无空格
3. 类名称命名:
- 类总是使用驼峰格式命名,即所有单词首字母大写其余字母小写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
"""
★类名称命名:
类总是使用驼峰格式命名,即所有单词首字母大写其余字母小写。
类名应该简明,精确,并足以从中理解类所完成的工作。
常见的一个方法是使用表示其类型或者特性的后缀,例如:SQLEngine ,MimeTypes
对于基类而言,可以使用一个 Base 或者 Abstract 前缀
不要滥用 *args 和 **kwargs,可能会破坏函数的健壮性
"""
# 变量命名总结:
# 1.单下划线开头变量:protected
# 2.双下划线开头变量:private
# 3.双下划线开头,双下划线结尾:系统内置变量
"""
单下划线开头变量
_xxx,单下划线开头的变量,标明是一个受保护(protected)的变量,原则上不允许直接访问,但外部类还是可以访问到这个变量。
这只是程序员之间的一个约定,用于警告说明这是一个私有变量,外部类不要去访问它。
print(stu._name) 当要输入_name时,pycharm不会进行_name的提示
print(stu.age) 当要显示age时,pycharm会进行age的提示
"""
class Student:
def __init__(self, name, sex):
self._name = name
self.sex = sex
stu = Student('zyf', 'Male')
print(stu._name) # 单下划线protected的变量,原则上不允许直接访问 输出:zyf
print(stu.sex) # age可以直接访问 输出:Male

"""
双下划线开头
__xxx,双下划线开头的,表示的是私有类型(private)的变量。
只能是允许这个类本身进行访问了, 连子类也不可以.
用于命名一个类属性(类变量),调用时名字被改变
(在类Student内部,__name变成_Student__name,如 self._Student__name)
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。仍然可以通过_Student__name来访问__name变量:
"""
class Person:
def __init__(self, name):
self.__name = name
per = Person('zyf2')
print(per._Person__name) # 输出zyf2 但是无法直接访问__name

"""
双下划线开头,并且以双下划线结尾
__xxx__,以双下划线开头,并且以双下划线结尾的,是内置变量.
内置变量是可以直接访问的,不是 private 变量,如__init__,__import__或是__file__。
★不要自己定义这类变量
xxx_,单下划线结尾的变量一般只是为了避免与 Python 关键字的命名冲突
USER_CONSTANT,大写加下划线,对于不会发生改变的全局变量,使用大写加下划线
"""

# 函数命名总结:
# 1.私有方法:小写和一个前导下划线
# 2.特殊方法(魔术方法):小写和两个前导下划线,两个后置下划线
# 3.函数参数:小写和下划线,缺省值等号两边无空格

"""
函数
总体而言应该使用,小写和下划线
私有方法 : 小写和一个前导下划线
这里和私有变量一样,并不是真正的私有访问权限。
同时也应该注意一般函数不要使用两个前导下划线(当遇到两个前导下划线时,Python 的名称改编特性将发挥作用)。特殊函数后面会提及。
#特殊方法 : 小写和两个前导下划线,两个后置下划线
#这种风格只应用于特殊函数,比如操作符重载等。
#函数参数 : 小写和下划线,缺省值等号两边无空格
"""
# 私有方法
class PrivateCase:
@staticmethod
def _secrete():
print(r"Don't test me")
priC = PrivateCase()
priC._secrete() # _secrete为protected member

# 特殊方法(魔术方法)
def __add__(self, other):
return int.__add__(other)

# 函数参数
def connect(self, user=None):
self._user = user

常用类库

str

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
1.是否以start开头:str.startswith('start')
是否以end结尾:str.endswith('end')
是否全为字母或数字:str.isalnum()
是否全字母:str.isalpha()
是否全数字:str.isdigit()
是否全⼩写:str.islower()
是否全⼤写:str.isupper()
2.全部⼤写:str.upper()
全部⼩写:str.lower()
⼤⼩写互换:str.swapcase()
⾸字母⼤写,其余⼩写:str.capitalize()
⾸字母⼤写:str.title()
3.搜索指定字符串,没有返回-1:str.find('t')
指定起始位置搜索:str.find('t',start)
指定起始及结束位置搜索:str.find(’t',start,end)
从右边开始查找:str.rfind('t')
搜索到多少个指定字符串:str.count('t')
上⾯所有⽅法都可⽤index代替,不同的是使⽤
index查找不到会抛异常,⽽find返回-1
1. 替换old为new:str.replace('old','new')
替换指定次数的old为new:
str.replace(‘old','new',maxReplaceTimes)
2. 去两边空格:str.strip()
去左空格:str.lstrip()
去右空格:str.rstrip()
去两边字符串:str.strip(‘d’)
相应的也有lstrip,rstrip
3. str.join() ⽅法⽤于将序列中的元素以指
定的字符连接⽣成⼀个新的字符串。
s1.join(seq),s1=“-“,seq是你要连接的序列
4. print('Hi, %s, you have $%d.' % ('linda',
100000000))
print('Hello, {0}, 成绩提升了
{1:.1f}%'.format('⼩明', 17.125))

os

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
os.sep:取代操作系统特定的路径分隔符
os.name:指⽰你正在使⽤的⼯作平台。⽐如对于Windows,它是'nt',⽽对于Linux/Unix⽤户,它是'posix'
os.getcwd:得到当前⼯作⽬录,即当前python脚本⼯作的⽬录路径。
os.getenv()和os.putenv:分别⽤来读取和设置环境变量
os.listdir():返回指定⽬录下的所有⽂件和⽬录名
os.remove(file):删除⼀个⽂件
os.stat(file):获得⽂件属性
os.chmod(file):修改⽂件权限和时间戳
os.mkdir(name):创建⽬录
os.rmdir(name):删除⽬录
os.removedirs(r“c:\python”):删除多个⽬录
os.system():运⾏shell命令
os.exit():终⽌当前进程
os.linesep:给出当前平台的⾏终⽌符。例如,Windows使⽤'\r\n',Linux使⽤'\n'⽽Mac使⽤'\r'
os.path.split():返回⼀个路径的⽬录名和⽂件名
os.path.isfile()和os.path.isdir()分别检验给出的路径是⼀个⽬录还是⽂件
os.path.existe():检验给出的路径是否真的存在
os.listdir(dirname):列出dirname下的⽬录和⽂件
os.getcwd():获得当前⼯作⽬录
os.curdir:返回当前⽬录('.'
os.chdir(dirname):改变⼯作⽬录到dirname
os.path.isdir(name):判断name是不是⽬录,不是⽬录就返回false
os.path.isfile(name):判断name这个⽂件是否存在,不存在返回false
os.path.exists(name):判断是否存在⽂件或⽬录name
os.path.getsize(name):或得⽂件⼤⼩,如果name是⽬录返回0L
os.path.abspath(name):获得绝对路径
os.path.isabs():判断是否为绝对路径
os.path.normpath(path):规范path字符串形式
os.path.split(name):分割⽂件名与⽬录(事实上,如果你完全使⽤⽬录,它也会将最后⼀个⽬录作为⽂件名⽽分离,同时它不会判断⽂件或⽬录是否存在)
os.path.splitext():分离⽂件名和扩展名
os.path.join(path,name):连接⽬录与⽂件名或⽬录
os.path.basename(path):返回⽂件名
os.path.dirname(path):返回⽂件路径

Error

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
AssertionError 断⾔语句(assert)失败
AttributeError 尝试访问未知的对象属性
EOFError ⽤户输⼊⽂件末尾标志EOF(Ctrl+d)
ImportError 导⼊模块失败的时候
IndexError 索引超出序列的范围
KeyError 字典中查找⼀个不存在的关键字
KeyboardInterrupt ⽤户输⼊中断键(Ctrl+c)
MemoryError 内存溢出(可通过删除对象释放内存)
NameError 尝试访问⼀个不存在的变量
NotImplementedError 尚未实现的⽅法
OSError 操作系统产⽣的异常(例如打开⼀个不存在的⽂件)
OverflowError 数值运算超出最⼤限制
RuntimeError ⼀般的运⾏时错误
StopIteration 迭代器没有更多的值
SyntaxError Python的语法错误
IndentationError 缩进错误
TabError Tab和空格混合使⽤
SystemError Python编译器系统错误
SystemExit Python编译器进程被关闭
TypeError 不同类型间的⽆效操作
UnboundLocalError 访问⼀个未初始化的本地变量(NameError的⼦类)
ValueError 传⼊⽆效的参数
ZeroDivisionError 除数为零

连接数据库

python连接数据库

pyton连接数据库需要先安装pymysql模块:pip install pymysql
安装完成后导入pymysql模块:import pymysql
python连接数据库主要分五个步骤:
step1:连接数据库
step2:创建游标对象
step3:对数据库进行增删改查
step4:关闭游标
step5:关闭连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# 1. 连接数据库,
conn = pymysql.connect(
host='localhost',
user='root',
password='redhat',
db='helloTest',
charset='utf8',
# autocommit=True, # 如果插入数据,, 是否自动提交? 和conn.commit()功能一致。
)
# ****python, 必须有一个游标对象, 用来给数据库发送sql语句, 并执行的.
# 2. 创建游标对象,
cur = conn.cursor()
# 3. 对于数据库进行增删改查
# 1). ************************创建数据表**********************************
try:
create_sqli = "create table hello (id int, name varchar(30));"
cur.execute(create_sqli)
except Exception as e:
print("创建数据表失败:", e)
else:
print("创建数据表成功;")
## 2). *********************插入数据****************************
try:
insert_sqli = "insert into hello values(2, 'fensi');"
cur.execute(insert_sqli)
except Exception as e:
print("插入数据失败:", e)
else:
# 如果是插入数据, 一定要提交数据, 不然数据库中找不到要插入的数据;
conn.commit()
print("插入数据成功;")
# 3). *********************插入多条数据****************************
try:
info = [(i, "westos%s" %(i)) for i in range(100)]

# *********************第一种方式********************
# %s必须手动添加一个字符串, 否则就是一个变量名, 会报错.
insert_sqli = "insert into hello values(%d, '%s');"
for item in info:
print('insert语句:', insert_sqli %item)
cur.execute(insert_sqli %item)

# *********************第二种方式********************
insert_sqli = "insert into hello values(%s, %s);"
cur.executemany(insert_sqli, info )
except Exception as e:
print("插入多条数据失败:", e)
else:
# 如果是插入数据, 一定要提交数据, 不然数据库中找不到要插入的数据;
conn.commit()
print("插入多条数据成功;")
# 4). **************************数据库查询*****************************
sqli = "select * from hello;"
result = cur.execute(sqli) # 默认不返回查询结果集, 返回数据记录数。
print(result)
print(cur.fetchone()) # 1). 获取下一个查询结果集;
print(cur.fetchone())
print(cur.fetchone())
print(cur.fetchmany(4)) # 2). 获取制定个数个查询结果集;
info = cur.fetchall() # 3). 获取所有的查询结果
print(info)
print(len(info))
print(cur.rowcount) # 4). 返回执行sql语句影响的行数
# 5). 移动游标指针
print(cur.fetchmany(3))
print("正在移动指针到最开始......")
cur.scroll(0, 'absolute')
print(cur.fetchmany(3))
print("正在移动指针到倒数第2个......")
print(cur.fetchall()) # 移动到最后
cur.scroll(-2, mode='relative')
print(cur.fetchall())
# 4. 关闭游标
cur.close()
# 5. 关闭连接
conn.close()

获取表的字段名和信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#首先导入所需要的模块
import time
import pymysql
#然后进入主程序部分:此部分用with语句编写(with语句实现的效果是: with语句执行结束, 如果成功, 则提交改变的数据, 如果不成功, 则回滚.)
conn = pymysql.connect(
host='localhost',
user='root',
password='redhat',
db='helloTest',
charset='utf8',
# autocommit=True, # 如果插入数据,, 是否自动提交? 和conn.commit()功能一致。
) #连接数据库
with conn: #主程序with语句部分
# ****** 判断是否连接?
print(conn.open) # True
# 2. 创建游标对象,
cur = conn.cursor()
# 3).
sqli = "select * from hello;"
result = cur.execute(sqli) # 默认不返回查询结果集, 返回数据记录数。
# 显示每列的详细信息
des = cur.description
print("表的描述:", des)
# 获取表头
print("表头:", ",".join([item[0] for item in des]))
cur.close() #关闭游标,with语句内部
conn.close() #关闭指针,with语句外部
print("with语句之外:", conn.open) # 正确情况下会是False

基于mysql数据库银行转账功能实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#银行转账系统考虑因素主要包括:
#1). 判断两个银行卡号是否存在?
#2). 判断source_id是否有足够的钱?
#3). source_id扣钱
#4). target_id加钱
#测试时,首先在数据库中构造数据表bankData,在数据表中添加用户信息(包括用户帐号和账户内金额)
import pymysql
class TransferMoney(object):
# 构造方法
def __init__(self, conn):
self.conn = conn
self.cur = conn.cursor()
def transfer(self, source_id, target_id, money):
if not self.check_account_avaialbe(source_id):
raise Exception("账户不存在")
if not self.check_account_avaialbe(target_id):
raise Exception("账户不存在")
if self.has_enough_money(source_id, money):
try:
self.reduce_money(source_id, money)
self.add_money(target_id, money)
except Exception as e:
print("转账失败:", e)
self.conn.rollback()
else:
self.conn.commit()
print("%s给%s转账%s金额成功" % (source_id, target_id, money))

def check_account_avaialbe(self, acc_id):
"""判断帐号是否存在, 传递的参数是银行卡号的id"""
select_sqli = "select * from bankData where id=%d;" % (acc_id)
print("execute sql:", select_sqli)
res_count = self.cur.execute(select_sqli)
if res_count == 1:
return True
else:
# raise Exception("账户%s不存在" %(acc_id))
return False

def has_enough_money(self, acc_id, money):
"""判断acc_id账户上金额> money"""
# 查找acc_id存储金额?
select_sqli = "select money from bankData where id=%d;" % (acc_id)
print("execute sql:", select_sqli)
self.cur.execute(select_sqli) # ((1, 500), )
# 获取查询到的金额钱数;
acc_money = self.cur.fetchone()[0]
# 判断
if acc_money >= money:
return True
else:
return False

def add_money(self, acc_id, money):
update_sqli = "update bankData set money=money+%d where id=%d" % (money, acc_id)
print("add money:", update_sqli)
self.cur.execute(update_sqli)

def reduce_money(self, acc_id, money):
update_sqli = "update bankData set money=money-%d where id=%d" % (money, acc_id)
print("reduce money:", update_sqli)
self.cur.execute(update_sqli)
# 析构方法
def __del__(self):
self.cur.close()
self.conn.close()

if __name__ == '__main__':
# 1. 连接数据库,
conn = pymysql.connect(
host='localhost',
user='root',
password='redhat',
db='helloTest',
charset='utf8',
autocommit=True, # 如果插入数据,, 是否自动提交? 和conn.commit()功能一致。
)
trans = TransferMoney(conn)
trans.transfer(13997, 13998, 200) #账户13997向13998转账200

execl与xmind

问题

xlrd.biffh.XLRDError: Excel xlsx file; not supported

1
2
3
4
5
6
# 原因是最近xlrd更新到了2.0.1版本,只支持.xls文件。所以pandas.read_excel(‘xxx.xlsx’)会报错。
# 可以安装旧版xlrd
pip uninstall xlrd
pip install xlrd==1.2.0
# 也可以用openpyxl代替xlrd打开.xlsx文件:
df=pandas.read_excel(‘data.xlsx’,engine=‘openpyxl’)

装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import random
import time


def time_count(func):
def wrap(*args, **kwargs):
time_flag = time.time()
temp_result = func(*args, **kwargs)
print(("time cost:", time.time() - time_flag))
return temp_result

return wrap


@time_count
def loop_time(x, y):
result = 0
for i in range(x, y):
time.sleep(random.choice((0.1, 0.2, 0.3)))
result = x + y
return result

if __name__ == '__main__':
print((loop_time(1, 2)))

远程操作linux

1
pip install paramiko
1
2
3
4
5
6
7
8
第一步:导入paramiko
第二步:创建SSHClient实例对象:ssh = paramiko.SSHClient()
第三步:即使没有公钥也可以访问:ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
第四步:连接远程linux机器:ssh.connect('linux所在机器的host',SSH端口号一般默认22,‘登录linux的用户名’,‘对应的密码’)
第四步:执行linux命令:ssh.excute_command('pwd'),执行多条命令用;隔开
第五步:获取输入输出及错误:把第四步赋值给stdin,stdout,stderr = ssh.excute_command('pwd;mkdir aaaa;ls')
传文件:sftp = ssh.open_sftp() sftp.put('源文件',“要拷贝的地址”) sftp.get()--从Linux往Windows拷贝
结束时候一定要加上 ssh.close

example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import paramiko

# 创建SSHClient实例对象
ssh = paramiko.SSHClient()
# 调用方法,标识没有远程机器的公钥,允许访问
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接远程机器 地址端口用户名密码
ssh.connect("192.168.13.128",22,"root","111111")
# 创建目录
ssh.exec_command("pwd")
ssh.exec_command("mkdir test")
ssh.exec_command("cd test")
stdin,stdout,stderr = ssh.exec_command("pwd")
print(stdout.read())
ssh.close()
1
2
3
4
5
6
7
8
9
10
11
import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.13.128',22,'root','111111')
stdin,stdout,stderr = ssh.exec_command('ls')
print(stdout.read())
sftp = ssh.open_sftp()
sftp.put(r'E:\Downloads\test.py','/home/test.py')
stdin,stdout,stderr = ssh.exec_command('ls;cd /home;ls;pwd')
print(stdout.read())

json比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from jsoncompare import jsoncompare as json_comp

json_comp.long = int
json_comp.unicode = str
json_comp.xrange = range


a = [
{
"Key": "managed",
"Value": "yes"
}
]

b = [
{
"Key": "managed",
"Value": "No"
}
]

# Compare respecting each array's order
json_comp.are_same(a, b)

print(json_comp.are_same(a, b)[1])

python2exe

环境准备

最好用虚拟环境,不加其他无关的依赖

1
pip install pyinstaller 

favicon.ico在线制作:http://www.favicon-icon-generator.com/

构建exe执行文件

1
2
3
4
5
Pyinstaller -F -w -i mergepdf.ico mergepdf.py

Pyinstaller -F mergepdf.py 打包exe
Pyinstaller -F -w mergepdf.py 不带控制台的打包
Pyinstaller -F -w -i mergepdf.ico mergepdf.py 打包指定exe图标打包

官方文档:https://pyinstaller.readthedocs.io/en/stable/usage.html

参数

-h,–help 查看该模块的帮助信息
-F,-onefile 产生单个的可执行文件
-D,–onedir 产生一个目录(包含多个文件)作为可执行程序
-a,–ascii 不包含 Unicode 字符集支持
-d,–debug 产生 debug 版本的可执行文件
-w,–windowed,–noconsolc 指定程序运行时不显示命令行窗口(仅对 Windows 有效)
-c,–nowindowed,–console 指定使用命令行窗口运行程序(仅对 Windows 有效)
-o DIR,–out=DIR 指定 spec 文件的生成目录。如果没有指定,则默认使用当前目录来生成 spec 文件
-p DIR,–path=DIR 设置 Python 导入模块的路径(和设置 PYTHONPATH 环境变量的作用相似)。也可使用路径分隔符(Windows 使用分号,Linux 使用冒号)来分隔多个路径
-n NAME,–name=NAME 指定项目(产生的 spec)名字。如果省略该选项,那么第一个脚本的主文件名将作为 spec 的名字

参考

https://blog.csdn.net/weixin_42052836/article/details/82315118

阅读全文
Algolia