2018-07-12-python编程学习篇
一、面向对象编程
1.类与实例
类就是一个抽象的模板,通过构造函数将类实例化为一个个的对象。
Python中的类中的方法,无论是构造函数还是其他方法,都需要写上一个self参数,但传参的时候不用管这个东西。
数据封装什么的就不用说了,学过c++就没啥不懂得。
2.访问限制
Python的私有变量是在类里面定义变量名时在变量名前面加上双下划线来实现的,这时候外部无法直接访问,但是内部设置get方法和set方法,然后通过外部调用这些方法来改变他。
然后说一下命名规范,主要是我们使用单下划线是一种警告,意味着我这个变量是作为私有变量最好不要随意使用,然后双下划线是真的私有变量,最后前后双下划线是特殊变量,一般就不要这样命名了。
然后私有变量其实还是可以实现外部直接访问的,因为他是通过解析器改了变量名来实现私有化,不同的解析器改名规则可能不一样,因此尽量不要通过这种方法去访问!
3.继承和多态
继承就是子类继承父类所有的方法和属性,变量多态就是多个类型的变量可以同时调用同一接口,注意Python中是动态语言。调用的时候不一定要严格是子类或者父类类型,而是只要拥有相同的方法就可以了。
4.type函数可以获取对象类型,对于函数或者类,可以import types函数来进行比对。
然后另一种方法是使用isinstance,这种手段更加方便快捷,并且他可以测量类继承的关系,比type更有优势.
然后dir()可以获取一个对象所有的属性以及方法,对于特殊方法可以进行改写(__init__类型的),其他方法都不要以这种手段来命名。
然后就是一些测试对象属性以及方法的手段,例如setattr,getattr,hasattr等等。
5.然后就是类属性和实例属性的区别吧,类属性所有实例都有,实例属性只有实例本身才有,然后就是类属性不要和实例属性取相同的名字,不然实例属性还是会覆盖类属性的。
二、面向对象高级编程
1.types中的MethodType可以给实例绑定方法,当要给实例绑定的属性方法限定的时候,可以用__slots__,然后我实测,抽象类能用,子类会失效。
2.property主要是用来将类中的方法变为属性来调用,这样的话调用者既简短了调用代码的工作量,又可以在调用的时候对他输入的参数进行检查,就一举两得了。
3.多重继承主要是继承多个母类的意思,用法是将多个继承的类放在括号里面排一起就好了。
4.这一课程主要讲了一些定制类,主要是用来替换掉类中一些默认的方法的,如下:
__str__主要用来表达当实例被print的时候表示什么,你可以自定义__str__,然后用print打印一个实例,控制他的输出。
__repr__主要用来表达直接输入实例时候程序返回什么,控制了__repr__就可以控制输入实例名称的时候程序输出啥,一般不改的话,他是返回默认实例内存地址的。
__iter__控制类中迭代对象的方法。
__getitem__可以控制下标来取对象。
__getattr__控制当找不到属性的时候程序会怎么处理。
__call__控制程序默认的自己调用的方法,如生成实例c,然后c()的时候干什么。
5.Enum可以把一组常量定义在一起,然后通过引用常量的名称加上value来引用。
6.metaclass:pass
三:错误、调试以及测试
1.错误处理:try,except,finally三个要熟练,如果没有捕获错误的机制的话,那就使用python自带的错误栈机制去从上往下抛出源错误。然后logging可以记录源错误,然后使用记录错误的时候程序继续运行。然后学习一种思维是:如果捕获到错误又没法解决的话,可以不断继续往上抛,错误最好保留原样。
2.调试代码:Python中有几种不同的方式可以调试代码,第一种比较蠢所有语言通用,就是加print,第二种就是简单直接加个assert断言一个条件对不对,不对就抛出assert error,然后第三种就是使用python自带的pdb调试器,启用的时候自己加上 -m pdb就行了,然后就是pdb_settrace(),用于程序运行到这里的时候可以自动变为断点,然后就是logging,可以import logging,然后logging.basicConfig(level=logging.INFO)指定输出的级别,可以是info,debug,warming,error。
3.单元测试:采用unittest模块来执行,然后采用他提供的各种方法来检验程序是否合格,然后运行的时候采用unittest.main()来运行
4.文档测试:加载一个叫做doctest的模块可以把文档中的注释代码(doctest严格按照Python交互式命令行的输入和输出来判断测试结果是否正确。只有测试异常的时候,可以用...表示中间一大段烦人的输出。)来进行代码测试,通过这种方法测试代码是否可以通过单元测试。通过doctest.testmod()来调用。
四:IO编程
1.读取文件:python中文件读取的函数是open函数,可以接收encoding参数,errors参数,必要的参数是文件路径和打开方式,然后就是可以使用with语句,他会自动帮你使用close方法最后关闭文件,写文件的参数是write.
2.介绍一下另外两种数据读写对象,我们使用io里面的StringIO模块以及BytesIO模块来解决字符串以及二进制流在内存中的读写问题,生成对象以后使用write方法来写,使用getvalue方法来读取。
3.操作系统文件操作和目录都被封装在os中,但是有一些函数是直接封在os中,一些函数是在os.path中,然后就是环境变量都保存在os.environ
4.讲了python中序列化的模块,序列化的目的是为了保存内存中的对象转变为二进制流,然后保存在磁盘上面,然后反序列化以后对象只是内容一样,但是其他已经不一致了。然后py中的序列化模块为pickle,使用pickle.dumps以及pickle.loads来进行序列和反序列,但是这个是只能用在python而已,其他的话,一般web端是使用xml或者json数据协议来进行传输的,Python中加载完json模块以后直接使用json.dumps以及json.load来解决,然后要注意转换的时候有一些要注意方法,没法直接转,例如class类型等等,要自己指定转换的方法。
五:进程与线程
1.python下面的进程可以采用multiprocess模块来代替fork函数,毕竟windows下面是没有fork函数的,因此我们也采用了python中的multiprocess来加载process模块,然后通过process函数来生成进程,可以通过pool来批量生成子进程,普通子进程的生成可以用process来创建,close函数可以用于阻止新进程的创建,然后close函数用于关闭新创建的进程。进程之间的通信可以用pipe以及queue来实现。
2.python中使用threading.Thread模块函数来生成多线程,然后注意引进threading.Lock()函数生成锁,然后就是使用lock.acquire函数来生成锁,release函数释放锁,然后注意GIL是Python解释器设计的历史遗留问题,通常我们用的解释器是官方实现的CPython,要真正利用多核,除非重写一个不带GIL的解释器。
所以,在Python中,可以使用多线程,但不要指望能有效利用多核。如果一定要通过多线程利用多核,那只能通过C扩展来实现,不过这样就失去了Python简单易用的特点。
3.出于要解决所有线程要访问同一个变量而且每一个线程对应的变量最好又要是局部变量的需求,Python引入了ThreadLocal这一个对象,他就像是一个dictionary,这个dictionary是全局变量,然后每一个线程以自身作为key来访问他,就完美处理了这一问题,通过threading.local来生成。
4.计算密集型任务采用底层语言(当然是我大c语言),IO密集型采用脚本语言,因为大量时间都在进行IO操作,CPU空闲着,没必要采用高效率低开发效率的语言。
5.分布式计算:python中的multiprocessing模块中的子模块managers把网络通讯的细节封装得很好了,可以借助他来实现分布式计算,各个进程之间通过queue来进行通信。
6.正则表达式:先了解一些基础知识
'\d':表示匹配一个数字,'\w':标识匹配一个数字或者字母, '.':表示匹配任意字符
'*':表示匹配任意个字符(包括0个),'+':表示匹配至少一个字符,'?':表示匹配一或0个字符
{n}:代表匹配n个字符,{n,m}代表匹配n到m个字符
[a-zA-Z\_][0-9a-zA-Z\_]{0, 19}:表示前面一个字符(可以是a-z,A-Z,或者下划线),和面匹配同样的字符,但是数量可以是0到19个。
A|B可以匹配A或B,^表示行的开头,^\d表示必须以数字开头。
$表示行的结束,\d$表示必须以数字结束。
然后python中的正则表达式模块是re
split可以引入正则表达式,只要匹配到就不处理。用于切分字符串。
然后正则表达式对象还有分组的功能,主要用于提取想要的分组。group(0)永远是整个字符串。
要想不贪婪匹配(尽可能多匹配字符),只要匹配的字符串后面加上?就可以了。
预编译可以用re.complie()来先编译,后面直接match就可以了。
六:常见的内建模块
1.第一个内嵌模块是datetime,主要是用于处理关于时间的问题,首先获取当前时间是datetime.now,获取完当前时间之后可以调用timestamp方法把他变成所谓的时间戳,一般而言使用时间戳来保存时间是一种比较好的做法,因为时间戳与我们的时区无关。然后使用fromtimestamp可以转换成时间。然后str与datetime可以互相转化,str转datetime是调用strptime来实现的,然后就是strftime可以把datetime转化为str.然后使用timedelta方法来实现所谓的时间加减。
2.第二个内嵌模块是collections,主要是讲了namedtuple,他可以帮你自定义一些tuple对象生成,可以通过属性而不仅仅只是索引来访问这个tuple.然后是deque函数,这个可以帮你自定义一个dict对象,然后拥有一些方法可以很方面地处理这些dict对象,例如appendleft方法等等。然后是defaultdict函数,主要是他可以帮你处理dict对象出错时候的错误反馈。然后是Orderdict,这个主要是可以以插入的顺序帮你把dict里面的属性来排序。最后一个是counter,他是一个简单的计数器,可以帮你计算一个字符串里面各个字母出现的频率。
3.第三个内嵌的模块是base64模块,base64的原理是这样的,先把三个字节组在一起,然后24b分为3组,也就是一组6bits,对应10进制里面一个小于64的数字,这样的话就直接对应base64的表了。使用base64.b64encode就可以进行编码了。出现+以及/的话就需要进型urlsafe_b64encode来处理,这是因为url中不能出现那个+以及/.最后要注意因base64是把3个字节变为4个字节,所以base64编码一定是4的倍数,然后是=是用来填充的,所以所出现=的字符串都会考虑是base64编码。
4.struct模块用于处理字节以及int,float等的转换。
5.hashlib用于调用哈希算法,主要用于生成摘要digest,通过hashlib.md5()等方法来使用,打印出来的话用digest就可以了。
6.为了防止黑客采用彩虹算法来破解哈希算法,所以提出了增加salt的想法来处理这些事情,然后python中增加了hmac这个模块,包含了标准的加salt算法,只要制定message,salt,digestmod算法就可以处理这个问题。使用hma.new来生成。
7.接下来讲一个操纵迭代对象的函数itertools,itertools.count会创建一个无限的迭代器,然后是repeat负责把一个元素无限重复下去,可以加一个数字制定重复的数字。chain函数负责联合两个更大的迭代对象。groupby负责把相同的元素组合起来放在一起。
8.主要学习了如何处理上下文的语句,使用contextlib中的contextmanager模块可以直接定义一个decorate接收一个generator,然后再接着一个with语句就可以定义代码执行的上下文环境了。如果想python自己生成一个context的话,可以直接加载一个closing,他会自己搞定上下文环境。
9.urllib模块主要是引入request这个模块来模拟发包,我们可以采用urlopen这个方法来打开指定的url,然后如果是要引入post方法的话就直接把data传给parse就可以了.
10.解析xml格式有两种方法,一种是DOM,他会把整个xml格式读入内存,然后可以遍历所有的节点,然后另外一个是SAX方法,是边读入内存边解析的,无法遍历所有节点,所有事件的处理方法都要自己定义,但是优点是内存占用小很多, 所以现在使用这个的占主流.
相应的引入模块是from xml.parsers.expat import ParserCreate,引入以后创建一个事件处理方法就可以解决问题了.
11.解析html的话就直接引入from html.parser import HTMLParser就可以了,然后要字节定义那些事件,毕竟html可以说是那个xml格式的一种子集来着,只是格式要求没那么严格而已,利用html.parse可以直接吧html中文本图像什么的给解析出来.
七.常见的第三方模块
1.pillow模块主要是用于python中的图像处理,可以用于对现有图像的处理或者是直接生成新图像,应用起来比较方便,对应的2.7版本是PIL模块,如果是3的话就是直接pillow。
2.第二个是requests模块,注意python自带的是request,相比之下requests比较直接,只要用requests.get或者requests.post方法直接打开就行了,put以及delete都一样,然后就是状态码什么的都直接加上属性值(例如status_code)等就可以了,然后就是其他的例如指定属性值(user-agent等直接放在headers里面制定)就可以了。
3.chardet是用来检测编码字符集用的,直接加载chardet后直接使用所谓的chardet.detect(放数据)就可以猜测了,会有个成功率的问题。
4.psutil模块主要做运维的时候获取系统信息用,例如cpu,内存,磁盘等等,但是需要python-dev的支持下才能使用,这里由于官方的py3-dev尚未放出来,所以先跳过。
5.virtualenv模块用于虚拟出一个python环境,然后直接使用virtualenv命令虚拟出一个环境以后可以跟别的python环境隔绝出来,这样各个项目之间就可以使用各自的python环境互相不影响。(感觉这个以后会有永达的时候)
6.tkinter是python自带的gui编程库,可以满足基本的GUI界面编写需要,如果是py3的话就需要直接使用apt-get install 来安装。