2019/06/15日知识总结

目录

测试过程中遇到生产问题怎们办?

如何评价一个测试用例是一个好的测试用例?

数据不一致问题举例及问题产生原因?

自己在业务推广中的工作?

测试工作中指出需求不当之处,给出依据及解决方案?

需求讲解过程中指出隐形需求提前规避了特定场景的缺陷问题

测试人的自我修养

您在从事性能测试工作时,是否使用过一些测试工具?如果有请试述该工具的工具原理,并以一个具体的工作中的例子描述该工具是如何在实际工作中应用的?

怎样做好测试计划?

系统测试阶段低级缺陷较多怎么办?

缺陷流落到客户哪里怎么办?

代码会审?

功能测试和性能测试的区别?

状态为已修改的缺陷,实际没有修改怎么办?

性能测试什么时候开始最合适?

回归测试中未解决的缺陷如何处理?

针对数十个安卓应用市场渠道包,请问如何进行大体的功能验证,简述思路?

注册模块如何测试?

APP测试和Web测试有哪些不同之处?

alpha测试和beta测试的区别?

写一个SQL来查询分数前5的所有人?

列举Linux中常用的命令

Android手机和IOS手机系统有什么区别?

简要介绍下安卓系统四层架构?

简单介绍下Android SDK中自带的几个工具/命令的功能?

常用的adb命令有哪些?写个简单的脚本并解释其含义?

测试过程中遇到app出现crash或者ANR,你会怎么处理?

请简单介绍一下实用过的安卓UI自动化测试工具?

你觉得app的性能测试,即专项测试,需要重点关注那些方面?

你们公司的测试流程?

缺陷BUG的几个要素?

白盒和黑盒测试的区别?

如何做测试分析?

如果项目周期短,测试人力匮乏,怎么协调测试?

自动化测试用例编写的规范

CAS认证问题

Token问题

Json串对比问题

Fiddler抓包问题

存储过程相关问题

Python的特点和优点是什么?

深拷贝和浅拷贝的区别是什么?

列表和元组有什么不同?

Python中三元表达式?

Python中如何实现多线程?

解释Python继承?

什么是Flask?

如何在Python中管理内存?

Python中help()函数和dir()函数?

当退出Python时是否释放所有内存分配?

Python字典

能否解释下*args和**kwargs?

编程实现计算文件中大写字母数

如何随机打乱列表中元素,要求不引用额外的内存空间?

解释Python中的join()和split()?

如何删除字符串中的前置空格?

如何将字符串转换为小写?

Python中的pass语句作用?

请解释Python中的闭包?

为什么标示符不建议使用下划线开头?

Redis

kafka

视图

Python中JSON文件处理

__file__作用以及模块导入方法

Python中的nose模块

Python中的Super模块

Python中函数参数传递

Python中的元类(metaclass)

python中类变量和实例变量

Python自省

Python字典推导式

Python中单下划线和双下划线

Python字符串格式化:%和.format

Python迭代器和生成器



首先,根据问题情况先定义个大概范围,然后看看在测试环境能不能重现,若能重现则在抓包工具、节点日志下截取错误日志信息,协助研发定位问题解决问题。记录问题及问题产生原因,自我反思为何会出现这种问题,是不是测漏了、哪里测漏了、为什么测漏?

其次,标注测试用例,重点回归;

最后,归档记录问题,避免后续出现类似问题;

A、测试用例书写格式正确、描述清晰, 其他测试人员拿到测试用例可以在不询问写作人的情况下正常执行下去;

B、测试用例对测试点覆盖完全,也就是说测测过程中发现的问题基本都是通过测试用例发现的,发现的比例越高越好, 越高说明测试用力的防护能力越强,当然测试用例不可能特别完备,在我们执行测试用例的过程,如果bug不是通过用例发现,我们需要对用例进行增加,这样我们下一次就可以把这个问题给防护住。(但是不是所有的bug都需要增加测试用例)(简单说就是bug尽可能都是测试用例发现的);

C、测试用例所属功能上线后,用户反馈好,说明测试用例关注的点都是用户care的点;

产生问题原因:

A、事务回滚导致;

B、历史遗留问题,导入模块未校验;

在排班系统配班以后,若为启用网点则会将相应的班次信息发送给调度系统,在月度排班计划表模块月度轮休导入功能导入100条数据,若前50条成功,第51条失败,数据库事务回滚,前50条数据同样也未入库,但因执行一条SQL则将相应信息发送调度,则前50条信息已发送调度,造成两边数据不一致;

解决方法:

导入过程中执行一条SQL后先不发调度,记录具体数据,待所有SQL均执行完后数据入库,统一将数据发送调度;

问题较难发现原因:

若导出失败后,删除出错信息继续导入,则继续导入后数据正确;若导入失败后,放弃该批数据重新导入,则会造成两边系统数据不一致;

总结经验:

验证过程中的每一个操作都应该核对相应数据的准确性,不应该只注重结果;

  • 自己在业务推广中的工作?

A、负责沟通群中问题解答,指导业务具体操作;

B、根据业务逻辑,查询问题定位问题产生的具体场景;

  • 测试工作中指出需求不当之处,给出依据及解决方案?

A、巴枪H5页面替班操作,原有替班逻辑,若A有1,2,...,n个班次,其申请B顶替其1,2,班次,完成申请流程后,又申请C顶替其剩余班次,则会把原A与B之间的替班记录完全删除掉,但B已收到A替班成功信息,造成B当天去上班的情况;

B、解决方案:按天替班,不存在单一班次替班问题,若出现A申请B替成功后,又申请C去替的情景,靠业务、营运到地区进行宣导;

  • 需求讲解过程中指出隐形需求提前规避了特定场景的缺陷问题

A、根据业务了解程度,指出删除替班数据同时删除对应的轮休指出所有场景;

B、指出根据轮休生成替班的所有场景;

  • 测试人的自我修养

  1. 扎实的基本工:熟练掌握测试基本知识,各种测试方法,相关测试业务,通过不断总结测试经验,培养测试敏感度等;
  2. 良好的沟通和协调能力:与项目经理、开发、测试等建立良好和有效的沟通,谨记对事不对人,不进行没有必要的争论,保证测试工作的梳理进行为第一原则;
  3. 传统测试观念的改变:学会换位思考:功能测试的第一原则时模拟所有可能出现的场景进行测试。所以测试时要尽可能的将自己也当成一个真实的用户,换位思考,也许一些新的测试idea就诞生了;bug发现者到bug预防者:bug的发现只是亡羊补牢之举,而预防则是制表治本之方;预防应该从两个方便出发:一是深挖产品需求逻辑,窥一斑而识全豹,要有牵一发而动全身的认识,从而督促产品人员细心和严谨;二是与开发携手,通过模块问题早预防,逻辑复杂模块早沟通,避免疏忽造成问题;
  4. 测试工具熟练使用,代码编程能力:勤于总结不同需求或者相应对应的测试工具,分析同类的工具的优缺点,以及如何选取不同的测试工具在测试项目的时候可能存在的问题,问题的解决办法等等;拥有良好的代码编程能力,是为了辅助我们更好的测试,提高测试效率。它是我们通向高级测试工程时,测试架构师的桥梁;
  5. 长远的工作计划:对测试行业有一个清晰的认知,对自己所在测试领域有渗透的了解;
  • 您在从事性能测试工作时,是否使用过一些测试工具?如果有请试述该工具的工具原理,并以一个具体的工作中的例子描述该工具是如何在实际工作中应用的?

使用过LoadRunner该工具能够录制测试人员的操作步骤,然后对这个操作步骤模拟出多个用户来播放出来;

1、Visural User Genertor创建脚本,选择协议,录制脚本,编辑操作;

2、中央处理器调度虚拟用户。创建场景,选择脚本,建立虚拟用户,设计shedual,设置ip spoofer;

3、运行脚本分析shedual;

4、分析测试结果;

  1. 理解系统。从整个系统的高度了解被测试系统必须满足的功能和非功能性需求。利用涉及整个系统的文档,形成对系统的整体了解;
  2. 及早介入:为了了解项目,测试人员应该在系统的开始阶段介入,可以增加对客户需求,客户问题,潜在风险,以及最重要的功能方面的理解;
  3. 测试期望:程序员的期望是什么?客户的期望时什么?销售对测试的期望又是什么?测试目标必须是绝对的,以免说不清楚是否达到目标;
  4. 吸取教训:把以前工作中学习到的经验教训运用过来,对确定测试策略很有作用;
  5. 工作量大小:完成测试需要多少工作日?需要多少测试人员?
  6. 技术选择:系统会选择什么技术?系统会采用什么架构?这些信息有助于测试策略和测试工具;
  7. 时间表:系统开发和测试分配的时间有多长?截止日期时什么时候?

公司有预测试流程,会在开展测试活动之前对主要功能点的正常流程做一个测试,以判断这个版本是不是可测试版本,如果低级缺陷较多,严重阻碍测试执行的话,我们会打回研发部,不能执行测试;

我们公司会尽可能的避免这种情况出现,让软件缺陷在内部得到解决,万一版本上线才发现问题,我们也会及时派技术人员在最短的时间内做出修改,把客户的损失降到最低;

对代码的评审过程,发现一些最基本的错误,方式时静态的代码走读方式,在一些大型软件的设计过程中,还是必不可少;

测试目的:

功能测试:检查实际软件的功能是否符合用户的需求,侧功能是不是去哪不实现,某个实现是不是有BUG;

主要为了发现以下错误:

是否有不正确或遗漏的功能;

功能实现是否满足用户需求和系统设计的隐藏需求;

能否正确接收输入并给出输出结果;

性能测试:验证软件质量的三个质量特性,可靠性、正确率和效率,主要测试产品的健壮性;

测试方法:

功能测试方法:按照需求说明述和测试用例,对产品的功能进行一步步的测试,找出产品功能是否全部实现;

性能测试:一般都是用性能测试工具对产品的健壮性进行评估,通过创建场景和虚拟用户来模拟真实环境,进行压力测试和负载测试;

加强项目质量管理,提高项目执行能力。如果测试人员发现了这样的问题,首先要弄清楚是什么原因导致这种情况,最终还是要督促开发人员,修改掉这些问题,若果是不能重现的问题或者老版本中遗留下来的问题不能修改的要做好标示;

一般在功能测试租后阶段执行,因为功能走通了,性能才有意义,总之性能测试要根据用户实际性能指标来操作,是一个很重要的测试活动,要根据软件的属性以及它的实际情况来制定策略;

实际项目中也会因为种种原因出现最后议论测试结束后,还有一些缺陷没有解决,那么对于问题的不同我们有不同的解决方式:严重问题:必须解决;功能性问题:可考虑后续版本中解决;一般性问题:可以不解决或者升级的时候解决;

可以自动化遍历某个目录下面的所有渠道包APK,然后循环安装、登录、操作、退出、卸载;

围绕数据入口、出口、数据库数据校验完整性;

  • APP测试和Web测试有哪些不同之处?

A、点击加载更好的分页处理技术,是否有重复的数据,数据显示是否完整,到达最后一页后是否还有数据进行显示;

B、数据的排序方式;

C、页面跳转是否正确;

D、出现异常情况是否有提示,是否跳转到已经设定好的默认页面,如断网情况下,显示网络未连接,数据加载失败,或者此页面没有数据显示,显示友好提示信息;

E、图片处理的地方,是否容易出现程序崩溃现象,主要是图片压缩机制;

F、前台展示数据,后台进行变动即增删改是否实时更新还是APP一开始运行再进行加载;

G、前台主动发出请求,后台数据库中是否存在相应的数据同时包括数据的关联性(商家的会员进行下订单,数据库中生成一条订单的记录的同时,生成一条积分记录,该会员的积分进行相应的变化);

H、手机app网络环境测试重点:主要是针对2G、3G、4G、wifi三种网络环境进行测试 ;

I、手机app兼容性测试:主要是针对android各个系统版本进行测试,及测试屏幕分辨率进行测试;

  • alpha测试和beta测试的区别?

前者在公司场地,由员工主导的测试行为;

后者在客户场地,由客户主导进行测试;

SELECT * FROM 分数表 ORDER BY DESC LIMIT 5;

SELECT TOP 5 * FROM 分数表 ORDER BY 分数 DESC;

cd:切换到某个目录;

ls:列出当前目录的所有文件、文件夹;

pwd:列出当前目录的路径;

cp:复制

mv:剪切

grep:管道

find:查找

rm:删除

ps:查看进程

kill:杀掉某个进程

cat:查看某个文件内容

tar:打包

chmod:赋权限

chown:改变文件的所有者

vim:文本编辑

  • Android手机和IOS手机系统有什么区别?

A、两者的运行机制不同,前者采用的是沙盒运行机制,安卓采用的是虚拟机运行机制;

B、两者后台制度不同:IOS中任何第三方程序都不能在后台运行;安卓中任何程序都能在后台运行,知道没有内存才会关闭;

C、IOS中用于UI指令权限最高,安卓中数据处理指令权限最高;

应用程序层、应用程序框架层、系统运行层、Linux核心层;

A、ddms:Dalvik Debug Monitor Service,是Android开发环境中的虚拟机调试监控服务;

B、monkey:Android中的一个命令行工具,可以运行在模拟器里或实际设备中。它向系统发送伪随机的用户事件流,如按键输入、触摸屏输入、手势笔输入等,实现对正在开发的应用程序进行压力测试。

C、uiautomator:其是Eclipse自带的用于UI自动化测试工具,可仿真APP上的单击、滑动、输入文本等操作;

D、adb:ADB的全称为Android Debug Bridge,就是起到调试桥的作用。通过ADB我们可以在Eclipse中方面通过DDMS来调试Android程序,就是debug工具。

(1)adb devices、adb install、adb uninstall、adb shell pm 、adb shell am

(2)adb shell monkey -p com.xiaoniu.finance -s 123 --throttle 500 --ignore-crashes --ignore-timeouts --ignore-security-exceptions -v -v -v 2000 > d:\xnonline-monkey-test1.txt

-p:app包名、

--throttle:每个操作的间隔时间,单位ms

--ignore-crashes:忽略崩溃

--ignore-timeouts:忽略超时

--ignore-security-exceptions:忽略安全异常

-v -v -v:日志详细等级,3个v代表最详细等级的日志

d:\xnonline-monkey-test1.txt:代表将产生的日志,放到本地PC的D盘,并命名为:xnonline-monkey-test1.txt

可以先把日志过滤出来: adb logcat | findstr xxxxx(过滤日志信息) ,然后再搜索其中的关键字,比如:exception、crash,看看是那些方法或者异常导致了问题的发送,初步定位问题原因后,可以交给开发人员去具体查找深层原因并修复。

appium:是一个移动端的自动化框架,可用于测试原生应用,移动网页应用和混合型应用,且是跨平台的。

robotium:是一款国外的Android自动化测试框架,主要针对Android平台的应用进行黑盒自动化测试,它提供了模拟各种手势操作(点击、长按、滑动等)、查找和断言机制的API,能够对各种控件进行操作。

内存、cpu占用、耗电量、流量、流畅度等

需求宣讲、需求评审、开发系分、测试系分、提测、几轮测试、灰度、上线;

测试系分主要包括:对需求的分析,对系统实现的分析,质疑不合理的设计,提出相应的风险为产品和研发补位,同时也要分析到测试会有哪些路径分支,避免遗漏;

A、总结描述;

B、缺陷内容:环境信息比如应用版本操作系统无线网络、重现步骤、相关日志、影响面、修复建议;

C、优先级或者严重程度;

A、黑盒就是不知道内部如何实现,只是从外部设计测试和执行用例,以达到业务覆盖,保障功能质量,通常以业务测试为主;

B、白盒测试就是了解内部实现机制,针对实现来设计测试和执行用例。通常来说通读代码实现是为了对白盒测试进行补充,怕有漏掉的分支,还有静态检查和覆盖率;

A、明确需求和需求有可能造成的影响;

B、探讨系统实现是否有风险,如果有风险有没有监控灰度回滚的策略;

C、制定测试策略,是否需要兼容性测试,性能测试,专项测试;

D、将需求整理成测试用例;

A、测试有压力,开发必然有压力,和开发一起砍需求;

B、系分和测分增加投入,做更精准的测试;

C、测试提前进入;

D、加强开发自测,拉去开发交付的用例;

E、加班

1.一个脚本是一个完整的场景,从用户登陆操作到用户退出系统关闭浏览器。

2.一个脚本脚本只验证一个功能点,不要试图用户登陆系统后把所有的功能都进行验证再退出系统
3.尽量只做功能中正向逻辑的验证,不要考虑太多逆向逻辑的验证,逆向逻辑的情况很多(例如手机号输错有很多种情况) ,验证一方面比较复杂,需要编写大量的脚本,另一方面自动化脚本本身比较脆弱,很多非正常的逻辑的验证能力不强。 (我们尽量遵循用户正常使用原则编写脚本即可)
4.脚本之间不要产生关联性,也就是说编写的每一个脚本都是独立的,不能依赖或影响其他脚本。

5、整个脚本中只对验证点进行验证,不要对整个脚本每一步都做验证。

6. 如果对数据进行了修改,需要对数据进行还原。

7. 测试用例的上下文必须有一定的顺序性,要能够互相连接起来;并且前置条件要清楚。

8. 每个测试用例粒度必须尽可能小,短小简单的测试用例易于调试。如果测试用例不得不长而复杂,则把它分成两个或更多的私有方法,并单独调用这些方法。

9. 尽量把重复任务放入一个方法中,这样它可以被多个测试用例调用。

10. 测试用例需要记录操作步骤

11. 测试用例执行出错要截图,从日志查看错误能一目了然

12. 测试用例要有合适的验证点,符合测试用例的期待结果。验证用是否存在的方法,如文件存在。

13. 测试用例只要不匹配预设的验证点,即使该测试用例还有未执行完的代码也要中断下面的执行,抛出合适的异常并提供详细的失败信息,然后设置该测试用例运行结果为失败

14. 测试用例要尽量处理所有的异常以健壮

15. 用例中尽量少的出现sleep,建议用"wait until ..."来代替;

16. 可以采用并发执行用例的方法来提升效,这需要case的独立性来做保证。

 

 

 

 

1、存储过程示例:

drop procedure if exists t_add; -- 如果存在t_add 存储过程则删除

create procedure t_add(num int)

begin

declare i int;

set i=0;

while i<num do

insert into sudents values ('',concat('张三',i+1),'男',18,'计算机','北京市海淀区');

insert into score values('',i+1,'计算机','81');

set i=i+1;

end while;

end;

call t_add(100000); -- 调用存储过程,插入10万条数据

  • Python的特点和优点是什么?

解释型、动态特性、面向对象、语法简洁、开源、丰富的社区资源;

深拷贝:是将对象本身复制给另一个对象。这意味着如果对象的副本进行更改时不会影响原对象。在Python中我们使用deepcopy()函数进行深拷贝;

浅拷贝:将对象的引用复制给另一个对象。因此如果我们在副本中进行更改,则会影响原对象。使用copy()函数进行浅拷贝。

主要区别在于列表是可变的,元组是不可变的;详见如下图片:

https://i-blog.csdnimg.cn/blog_migrate/d22e50dbc8ad86dde3e9649161a5d103.jpeg

会出现以下错误提示:

TypeError: ‘tuple’ object does not support item assignment

与C++不同,在Python中我们不需要使用?符号,而是使用如下语法:

[on true] if [expression] else [on false]

如果[expression]为真,则[on true]部分被执行。如果表示为假则[on false]部分被执行;

  • Python中如何实现多线程?

线程是轻量级的进程,多线程允许一次执行多个线程,Python是一种多线程语言,它有一个多线程包。GIL(全局解释器锁)确保一次执行单个线程。一个线程保存GIL并在将其传递给下一个线程之前执行一些操作,这就产生了并行的错觉。但实际上,知识线程轮流在CPU上。当然所有传递都会增加执行的开销。

一个类继承自另一个类,也可以说是一个孩子类/派生类/子类,继承自父类/基类/超类,同时获取所有的类成员(属性和方法)。

继承使我们可以重用代码,并且还可以更方便地创建和维护代码。Python支持以下类型的继承:

单继承----一个子类继承自单个基类;

多重继承----一个子类继承自多个基类;

多级继承----一个子类继承自一个基类,而基类继承自另一个基类;

分层继承---多个子类继承自同一个基类;

混合继承---两种或两种以上继承类型的组合;

Flask是一个使用Python编写的轻量级Web应用框架,使用BSD授权,其WSGI工具箱采用Werkzeug,模板引擎则使用Jinja2。除了Werkzeug和Jinja2以外几乎不依赖任何外部库。因为Flask被称为轻量级框架。

Flask的会话使用签名cookie来允许用户查看和修改会话内容。它会记录从一个请求到另一个请求的信息。但如果要修改会话,则必须有密钥Flask.secret_key。

Python用一个私有堆内存空间来放置所有对象和数据结构,我们无法访问它。由解释器来管理它。不过使用一些核心API,我们可以访问一些Python内存管理工具控制内存分配。

  • Python中help()函数和dir()函数?

help()函数返回帮助文档和参数说明;

dir()函数返回对象中的所有成员;

答案是否定的,那些具有对象循环引用或者全局命名控件引用的变量,在Python退出时旺旺不会被释放。

字典拥有键值对,其是可变的。

如果我们不知道将多少个参数传递给函数,比如当我们想传递一个列表或一个元组值时,可以使用*args;

当我们不知道将会传入多少关键字参数时,使用**kwargs会收集关键字参数。

当你不确定你的函数里将要传递多少参数时你可以用*args。例如,它可以传递任意数量的参数:

1. >>> def print_everything(*args):
2. for count, thing in enumerate(args):
3. ... print '{0}. {1}'.format(count, thing)
4. ...
5. >>> print_everything('apple', 'banana', 'cabbage')
6. 0. apple
7. 1. banana
8. 2. cabbage

相似的,**kwargs允许使用没有事先定义的参数名:

1. >>> def table_things(**kwargs):
2. ... for name, value in kwargs.items():
3. ... print '{0} = {1}'.format(name, value)
4. ...
5. >>> table_things(apple = 'fruit', cabbage = 'vegetable')
6. cabbage = vegetable
7. apple = fruit

*args和**kargs可以同时在函数的定义中,但是*args必须在**kwargs前面。

https://i-blog.csdnimg.cn/blog_migrate/b81f632c7784c7fc4d190effb1a487c8.jpeg

我们用 random 包中的 shuffle() 函数来实现。

[3, 4, 8, 0, 5, 7, 6, 2, 1]

join() 函数可以将指定的字符添加到字符串中。

‘1,2,3,4,5’

split() 函数可以用指定的字符分割字符串

[‘1’, ‘2’, ‘3’, ‘4’, ‘5’]

Python区分大小写

前置空格是第一个非空格字符前的所有空格,使用 lstrip() 函数来删除.

‘Ayushi ‘

如图这个字符串既包含前置空格也包含后置空格. 调用 lstrip() 函数去除了前置空格。如果想去除后置空格,使用 rstrip() 函数。

‘ Ayushi’

使用lower()函数;

转换为大写用upper()函数;

要检查字符串是否为全大写或全小写,使用isupper()和islower()函数。

我们在写代码时,有时可能只写了函数声明而没想好函数怎么写,但为了保证语法检查的正确必须输入一些东西,这个时候使用pass语句。

类似break语句可以跳出循环;

continue语句可以跳到下一轮循环;

如果在一个内部函数里。对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就是一个闭包。

因为Python中以下划线开头的变量为私有变量。如果不想让变量私有,就不要使用下划线开头。

 

json.dumps()和json.loads()是json格式处理函数(可以这么理解,json是字符串);

json.dumps()函数是将一个Python数据类型列表进行json格式的编码,可以这么理解,json.dumps()函数是将字典转化为字符串;

json.loads()函数是将json格式数据转换为字典,可以这么理解,json.loads函数将字符串转化为字典。

json.dump()和json.load()主要用来读写json文件函数。

代码示例一:

import json

# json.dumps()函数的使用将字典转化为字符串

dict1={"age":12}

json_info=json.dumps(dict1)

print("dict1的类型:"+str(type(dict1)))

print("json_info的类型:"+str(type(json_info)))

代码示例2:

import json

#json.loads函数的使用,将字符串转化为字典

json_info='{"age":"12"}'

dict1=json.loads(json_info)

print("json_info的类型:"+str(type(json_info)))

print("dict1的类型:"+str(type(dict1)))

代码示例3:

import json

data={'id':1,'name':'51zxw','password':'66666'}

print(type(data))

json_str=json.dumps(data)

print(type(json_str))

print(json_str)

# 写入data文件

with open('data.json','w') as f:

    json.dump(data,f)

# 读取data文件

with open('data.json','r') as f:

    data=json.load(f)

    print(data)

Python执行py文件的时候,默认就会把当前目录增加到sys.path中;

import os

# 打印文件当前的位置

print(__file__)

# 打印当前文件上一层目录

print(os.path.dirname(__file__))

print(os.path.dirname(os.path.abspath(__file__))) #打印当前文件的绝对路劲,获取当前文件上一层目录

os.path.abspath(__file__) 获取当前当前文件的绝对路劲 
os.path.dirname()获取当前文件上一层目录 ​​​​​​​

示例代码:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

class FooParent(object):

    def __init__(self):

        self.parent = 'I\'m the parent.'

        print ('Parent')

    def bar(self,message):

        print ("%s from Parent" % message)

class FooChild(FooParent):

    def __init__(self):

        # super(FooChild,self) 首先找到 FooChild 的父类(就是类 FooParent),然后把类B的对象 FooChild 转换为类 FooParent 的对象

        super(FooChild,self).__init__()   

        print ('Child')

    def bar(self,message):

        super(FooChild, self).bar(message)

        print ('Child bar fuction')

        print (self.parent)

if __name__ == '__main__':

    fooChild = FooChild()

    fooChild.bar('HelloWorld')

super()函数是用于调用父类(超类)的一个方法。

super()是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序,重复调用等等问题;

  • Python中函数参数传递

Python中变量可以理解是内存中一个对象的引用;

Python中strings、truples、numbers是不可更改的对象,而list、dict、set等则是可以更改的对象。

  • Python中的元类(metaclass)

Python中其实有三个方法,即静态方法(staticmethod)、类方法(classmethod)和实例方法;

def foo(x):
    print("executing foo(%s)"%(x))

class A(object):
    def foo(self,x):
        print("executing foo(%s)"%(x))

    @classmethod
    def class_foo(cls,x):
        print("executing foo(%s)"%(x))

    @staticmethod
    def static_foo(x):
        print("executing foo(%s)"%(x))
a=A()
# 正确调用
a.foo('lzl')
a.class_foo('lzl')
a.static_foo('lzl')

# A.foo('lzl')             # 错误调用
A.class_foo('lzl')
A.static_foo('lzl')

备注:

self、cls是对类或者实例的绑定,对于一般的函数来说我们可以调用foo(x),这个函数是最常用的,它的工作跟任何类、实例无关,而对于实例方法,我们知道在类里每次定义的时候都需要绑定这个实例,就是foo(self,x),原因:实例方法的调用离不开实例,我们需要把实例自己传给函数,调用的时候是a.foo(x),其实是foo(a,x)。类方法一样的,只不过其传递的是类而不是实例。

  • python中类变量和实例变量

类变量:

是可在类的所有实例之间共享的值,即它们不单独分配给每个实例的,例如下面的num_of_instance就是类变量,用于跟踪存在着多少个Test的实例;

实例变量:实例化后,每个实例单独拥有的变量。

  • Python自省

这个也是Python彪悍的特性;

自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型,简单一句就是运行时能够获得对象的类型,比如type()、dir()、getattr()、hasattr()、isinstance()。

  • Python字典推导式

d={key:value for (key,value) in iterable}
  • Python中单下划线和双下划线

class MyClass():
    def __init__(self):
        self.__superprivate='Hello'
        self._semiprivate=',world!'


mc=MyClass()
# print(mc.__superprivate)
'''
Traceback (most recent call last):
  File "C:/Users/Administrator/Desktop/12312312323.py", line 8, in <module>
    print(mc.__superprivate)
AttributeError: 'MyClass' object has no attribute '__superprivate'
'''
print(mc._semiprivate)

print(mc.__dict__)
'''
,world!
{'_MyClass__superprivate': 'Hello', '_semiprivate': ',world!'}
'''

__foo__:一种约定,Python内部的名字,用来区别其他用户自定义的命名,以防冲突,就如:__init__()、__del__()、__call__()这些特殊方法。

_foo:一种约定,用来指定变量私有。程序员用来指定私有变量的一种方式,不能用from module import * 导入,其他方面和公有一样访问;

__foo:这个有真正的意义:解析器用_classname__foo来代替这个名字,以区别和其他类相同的命名,它无法直接像公有成员一样随便访问,通过对象名._类名__xxx这样的方式可以访问。

  • Python字符串格式化:%和.format

.format在许多方面看起来更便利,对于%最烦人的是它无法同时传递一个变量和元组;

name = 'lzl'
print('hi there %s' % name)
>>>"{} {}".format("hello", "world")    # 不设置指定位置,按默认顺序
'hello world'
 
>>> "{0} {1}".format("hello", "world")  # 设置指定位置
'hello world'
 
>>> "{1} {0} {1}".format("hello", "world")  # 设置指定位置
'world hello world'
  • Python迭代器和生成器

关于生成器的创建问题:将列表生成式中[]改成()之后数据结构是否改变?是,从列表变为生成器。

1. >>> L = [x*x for x in range(10)]
2. >>> L
3. [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
4. >>> g = (x*x for x in range(10))
5. >>> g
6. <generator object <genexpr> at 0x0000028F8B774200>

通过列表生成式,可以直接创建一个列表。但是受到内存限制,列表容量肯定是有限的,而且创建一个包含百万元素的列表,不仅占用很大的内存空间,如:我们只需要访问前面的几个元素,后面大部分元素所占的空间都是浪费的。因此没有必要创建完整的列表,从而节省大量内存空间,在Python中我们可以使用生成器边循环边计算的机制即生成器。

  • 面向切面编程AOP和装饰器

装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事物处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用,装饰器的作用就是为已存在的对象添加额外的功能。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值