老男孩视频教程前四期整理

前言

学习python已经有些时日了,初时接触从某大神的博客开始看起,搭配环境,陆陆续续跟着敲着代码,算是熟悉了。然而,初时学python还是好奇的因素比较多,一些细节虽然当时能懂,过了近一年,也便淡忘,甚而之前做的一些注释,慢慢地也不解其意,总结有以下几点原因:

  1. 学的时候不能说不专心,只是一些侧重点没有特别注意,太依赖于大神写的博客,对python的知识不能系统的全局通观;
  2. 缺少总结,学到的知识只能成为一盘散沙,形不成一个体系,以致慢慢遗忘;
  3. 缺少编程的锻炼,拷贝大神的代码抑或自己照着敲代码,终究不是自己的思维,缺少项目的历练,没有练习,没法融会贯通。

所以,在这次学习python老男孩的视频培训课程,一是温习或者说“预习”之前学习的python知识,心里有点数,稍全面的理解;二是了解python究竟重点需要掌握的是什么,应该从哪些地方勤加历练,工作时注重哪些部分;三是了解现实的开发环境和状态是怎样的,脱离语言学习的实验室状态。

此次python的学习整理,将重点参考老男孩的视频教程,辅以之前大神博客的学习随笔和之前的一些理解,了解哪些是新的,哪些是之前学习的,去年和今年的python学习内容有多少异同,试图能在脑海中形成一个体系,循着这个体系尝试编程锻炼,不断地反馈出自己对python的理解。

Python教程前四天总结

       第一天:

这一天的课程主要是介绍了python的由来和发展,安装和环境准备,数据类型和运算,Unicode编码,导入模块,用户交互和格式化输出,循环控制和中断等内容。

  1. python版本的一些问题,python的版本目前有两类:2.x3.x,而2.x版本不一定比某些3.x版本低,因为在稍后的一些2.x版本出来之前,python3.x版本就出现了,目前稍新一点的python2.x版本是兼容3.x的,更为重要的是,目前linux的一些发行版本基本都是python2.x的,所以说现在目前使用较为广泛的还是python2.x,其中ubuntu系统的python版本一直是较新的,能够导入的模块也更全一些,截至笔者写这篇笔记,最新的稳定版本是2.11.
  2. python的声明变量:python的变量不需要声明,可以直接输入,数据类型是python自动决定
  3. 数据运算,乘方a**b,即ab次方
  4. Python的缩进:python语言的一个很明显的特征就是强制缩进,因为没有类似于C语言和JAVA等通过各种括号包裹各种模块的机制,一般是“四个空格”的缩进,其实利用IDE(Intergrated Development Environment,集成开放环境)工作更加方便。
  5. 循环控制,其中在python中,循环可以有以下的用法

for a in range(10):

print a**2

                这样就省却了其他语言类似加入一个i变量,递增循环

                continue:跳过本次执行,继续下一次执行;

                break:满足条件,整个循环停止

  1. 格式化输出和用户交互:raw_input,接受用户输入的字符串信息;input,接受用户输入的数字信息。格式化输出,如以下代码:

name = raw_input('please input your name:')

age = input('age:')

job = raw_input('Job:')

salary = raw_input('Salary:')

 

print '''

Personal information of %s:

     Name : %s

     Age  : %s

     Job  : %s

    Salary: %s

''' %(name,name,age,job,salary)

  1. 注释:python的单行注释:在句首加上#符号,pydev沿用eclipse加注释的方法,即ctrl+/的形式;多行注释,通过一对’’’添加。
  2. 使用和导入模块:from myMudule import myDef,即导入myMudule模块的myDef方法。
  3. 编码方式,unicode转为utf-8:enclde;utf-8转为unicode:decode,py文件设为utf-8格式,#codingutf-8 utf-8的编码方式是该文本下的ASCII字符依然是一个字节,非ASCII2字节

这一天的学习的只是一些基础,但是要能真正的掌握理解,需要一直勤于练习。

       第二天:

       这一天的课程主要包括文件的处理及file的方法,字符串、列表、元组、字典、集合等的处理和相应的方法。

  1. file的几种文件处理模式,r只读,w只写,a追加,r+b以读写模式打开,w+b以写读模式打开,a+b以追加及读模式打开,b是以binary形式打开的意思,一般这样采用,一个例子:

f = file('D:\myFile.txt','r')

for line in f.readlines():

    line = line.strip('\n').split(':')

print line

             其中strip('\n')即去除换行符,以”:”作为分隔符,以序列的形式输出

  1. file的几种方法:flush()强制刷新:即不用关闭文件,更新文本文件;seek():跳转到想要跳转到的位置,tell()告知目前读取文件的所在位置;xreadlines()返回一个迭代器,相较于readlines()更高效,是读取一行,内存存储一行,再显示出来,而readlines()是读取全文内容,再显示出来。(实际是xreadline()内部有一个yield机制)
  2. 字符串方法,find(substring,[start[,end]])在可指范围内查找字串,返回索引值;count返回找到子串的个数;split(str,’’)string转为list,以空格切分;join(list,’’)list转为string,以空格连接
  3. 列表与其他语言中的数组类似,f1 = [3,5,2,5],扩展append(),insert(index,object):从某一处添加对象进去,remove()删除,index()某一元素的索引,pop()删除最后一个,f1[2:5],返回index25,不包括5,即“顾头不顾尾”,[-5]最后5个,[5]5个,[1::3],从index=1开始,每3个取一个
  4. tuple是如f2 = (1,2,3,2,3)的形式,只是元组的元素不能被修改;
  5. 字典,以keyvalue保存 dic = { ‘name’:’focky’,’age’:23,’lily’:34},里面的元素是无序的,只能通过key来引用,词典的常用方法:dic.items():以列表的形式显示字典,两种读取字典的方式:

(1) for k,v in dic.items():

print k,v

(2) for i in dic:

print i,dic[i]

第二种效率更高,因为第一种还有一个转换成列表的过程

根据key获取value:直接dic[‘name’] = ‘focky’

setdefault()dictc3.setdefault('fuck',6):如fuck这个字段在字典中不存在,将默认赋给一个6的值

update()合并字典

浅复制,copy(),字典中如果存在列表,执行copy()方法后,虽然不同步更新列表的一些记录,但是里面的列表时通过更新的,而深复制,里面的内容是完全独立更新的。字典一般占用的内存大一点,因为它需要维护一个hash

  1. 集合,一般写作如name_set = {1,2,4,5},集合取交集:x&y,取差集:x-y,对称差集:x^y
  2. tab补全的一段代码:

try:

   import readline

except ImportError:

   print (“module readline not available”)

else:

   import rlcompleter

   readline.parse_and_bind(“tab:complete”)

这一天主要是几种数据类型的介绍方法等,平时要注意与其他语言相似数据类型的区别和相似点。

第三天:

       这一天的内容主要包括pydevpythonIDE的用法,函数的用法,yield的使用,几种内置函数及其使用,random生成验证码,MD5加密。正则表达式等内容,重点是函数的概念。

  1. pydev的搭建
  

(1)首先下载最新的python版本并在主机上安装,并在环境变量上Path系统变量加上python安装的具体路径;

(2)其次,下载eclipse,随便哪一个版本,可以下载java版本的,如果本机上没有安装jdk1.7及其以上版本,需要下载jdk并安装,安装完jdk后,需打开windows+R,输入cmd进入dos输出框:

出现上述字样,即代表jdk安装成功,如果不出现,需在系统变量设置(计算机-属性-高级系统配置-环境变量,添加如下内容:

创建JAVA_HOME变量,将jdk安装的具体路径添加至该变量上;

在系统变量里面的path下添加%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;前面如果没有‘;’符号,需要在前面添加该符号;

创建CLASSPATH变量,添加如下内容.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar

出现上图内容,即代表创建成功。

(3)然后下载pydev,将其解压,把它包括的两个文件夹(pluginsfeature)下的文件拷贝至ecplise下相同文件夹上面,开启eclipse,点击windows-preferences即可看到pydev,证明安装成功,点击File-New-Project,即可出现创建pythonproject的选项:

配置一个interpreter,即pydev基于的python环境。

点击New,然后添加python安装的路径即可,如此一个python Project即添加完成了。
 
  1. 重要的__init__.py文件,当创建一个python package的时候,默认创建一个__init__.py文件,如果其他模块想调用该package里面的函数等,需要这一文件,删除这一文件,这个package就会变成一个文件夹,不能被其他模块调用。
  2. 是否为主文件调用:每个py文件都有一个__name__值,该值表示py文件被当前的主文件调用还是其他文件调用,如果被当前主文件调用,则该值为__main__;如果被其他文件调用,则显示相应模块下的py文件路径。所以一个py文件中如果存在“if __name__==__main__,则该判断模块下的语句在该py文件被其他py文件调用时将不会执行。
  3. __file__:py文件的具体路径;__doc__该文件创建时添加的说明注释。
  4. 默认参数和可变参数:默认参数,在定义函数里面的参数设置默认值。可变参数,参数前面加*号,def show(*arg),调用函数时参数的数量可变,调用函数时可以传入列表,然后以show(*sequence)的形式传入。字典可变参数:如:

def show(**kargs):

    for item in kargs.items():

        print item

       

show(name="woca",age='dd',hh='df')或者user_dict={ name="woca",age='dd',hh='df},

show(**dict)

可传入可变变量和对应的参数。

  1. yield的使用:yieldpython的生成器。生成器的编写方法和函数定义类似,只是在return的地方改为yield。生成器中可以有多个yield。当生成器遇到一个yield时,会暂停运行生成器,返回yield后面的值。当再次调用生成器的时候,会从刚才暂停的地方继续运行,直到下一个yield。生成器自身又构成一个循环器,每次循环使用一个yield返回的值。

如下面的一个MyReadlines()方法即是xreadlines()的主要原理:

def MyReadlines():

    seek = 0

    while True:

        with open('D:/temp.txt','r') as f:

            f.seek(seek)

            data = f.readline()

            if data:

                seek = f.tell()

                yield data

            else:

                return

            

for item in MyReadlines():

print item

   这样即是实现了逐行读取数据,逐行读入内存,然后显示出来。通过加断点,debug状态下运行可以更清楚的看到这种现象。

  1. lambda表达式(也作匿名函数)

缩略函数:

temp = lambda x,y:x+y

print temp(4,4)

  1. 几种内置函数:

dir(a),得出对象a的几种方法;

var(a),a的更详尽的几个信息,包括注释、路径等;

reload()重新导入模块,因为无论写多少from file import demo类似字样,最终只会导入一次;

divmod(x,y):得到商和余数;

pow():乘方;

all():全为非0,则为True;

any():任意有非0,则为True

enumerate():得出带编号的循环,以元组的形式存储;

格式化输出:s=’ i am {0},{1}’ print s.format(‘alex’,’xxx’);

map(),re = map((lambda x: x+3),[1,3,5,6]),将函数对象依次作用于表的每一个元素;

filter():以过滤函数的形式过滤表里面的元素,返回一个经过过滤后的表;

reduce():累进的将函数作用于各个参数。reduce((lambda x,y: x+y),[1,2,5,7,9])

zip():多个等长的序列,每次循环时从各个序列分别取出一个元素。

ta = [1,2,3]

tb = [9,8,7]

tc = ['a','b','c']

for (a,b,c) in zip(ta,tb,tc):

print(a,b,c)

得出如下的结果:

(1, 9, 'a')

(2, 8, 'b')

(3, 7, 'c')

eval():运行字符串里面的运算或者实现字符串里面所要实现的东西

  1. 反射:字符串形式导入模块,字符串形式执行函数。

temp = 'mysqlHelper'

func = 'count'

 

model = __import__(temp)

Function = getattr(model, func)

  1. 生成验证码的方法:

import random

 

code = []

for i in range(6):

    if i == random.randint(1,5):

        code.append(str(random.randint(1,5)))#这里有个列表转为字符串的强制转换

    else:

        temp = random.randint(65,90)

        code.append(chr(temp))

print ''.join(code)

randint:随机产生整数,可设置范围,chr(temp)以数字作为序号,生成所对应的ASCII码,这里对应的是字母。这里有个字符串函数join,将列表的内容逐次添加到字符串中。

  1. MD5加密:这里有个常规开头:

import hashlib

hash = hashlib.md5()

 

hash.update('admin')

print hash.hexdigest()

  1. 序列化:

import pickle

li = ['nima',23,'shabi',666]

dumpsed = pickle.dumps(li)

print dumpsed

python特有的文本形式来生成对应的文本流;

loadsed = pickle.loads(dumpsed)

print loadsed

返回文本流导出来的原列表

pickle.dump(li, open('D:/temp.pk','w'))

result = pickle.load(open('D:/temp.pk','r'))

print result

加工文件,生成文本流。

  1. json

json式的序列化更加普遍,而pickle序列化后得出的文本流只有python可以读取。如下面的代码得出的结果是:

import json

serialized_obj = json.dumps(li)

print serialized_obj

print type(serialized_obj)

normal_obj = json.loads(serialized_obj)

print normal_obj

print type(normal_obj)

结果:

["nima", 23, "shabi", 666]

<type 'str'>

[u'nima', 23, u'shabi', 666]

<type 'list'>

加工文件,生成文本流,将dumps()方法改为dump()方法

  1. 正则表达式

d:数字,+:>=1;

w:字母或者‘|,_;

*:>=0;

?:01;

{m}出现次数;

{m,n}出现次数[m,n]

‘?:’ 连续匹配

正则表达式在python中属于re模块,有search(),match(),findall()方法,matchsearch的区别是match从头开始匹配,开头如果没有就直接返回None,search则是发现匹配为止,findall()则是查找所有匹配项。具体调用如:

result1 = re.search('(\d+)\w*(\d+)', 'aaaa2345fgd45566'),匹配后的result1是一个对象,通过group()方法分组返回匹配的字符串。

匹配ip地址:print re.findall('(?:\d{1,3}\.){3}\d{1,3}',ip)

  1. time模块

print time.time():显示当前时间的时间戳,从197011日零点开始经过的秒数

print time.gmtime()

print time.localtime() #返回出time.struct_time(tm_year=2016, tm_mon=4, tm_mday=28, tm_hour=6, tm_min=48, tm_sec=32, tm_wday=3, tm_yday=119, tm_isdst=0)

time.struct_time(tm_year=2016, tm_mon=4, tm_mday=28, tm_hour=14, tm_min=48, tm_sec=32, tm_wday=3, tm_yday=119, tm_isdst=0)

print time.strftime('%Y-%m-%d %H:%M:%S'),格式化输出时间

这一天介绍了多种方法,内置函数,一些常见功能的代码实现。

第四天:

这一天开始具体讲面向对象的概念,一个对象所拥有的一些特殊方法,装饰器的概念,异常处理等。

  1. 反射机制:解析如一些网页地址对应方法:

data = raw_input('请输入地址:')

array = data.split('/')

userspace = __import__('backend.'+array[0])

 

model = getattr(userspace, array[0])

func = getattr(model, array[1])

func()

   上述代码实现的就是输入网址,以/分割,调用某个模块下的某个方法。特殊方法getattr()是查询即时生成的属性。

  1. 装饰器

装饰器可以对一个函数、方法或者类进行加工,起到一个提高程序的重复利用性,增加程序的可读性等:

如下面的代码:

def outer(fun):

    def wrapper(arg):

        print '验证'

        fun(arg)

    return wrapper

 

@outer #装饰器

def Func1(arg):

    print 'func1',arg

 

Func1('alex')

检测到这个装饰器,先执行装饰器对应的函数的内容,根据装饰器的内容对函数进行操作。

  1. 面向对象

视频教程老师说的一段话我觉得很有道理,面向对象说起来,大家都道听途说;讲起来,大家都以现实中的某些具体事物来类比。然而真正做开发了,很多可以抽象,可以通过面向对象的方式来解决的,多数人却不易想到,所以,真正理解面向对象,需要多做相关方面的编程,才能逐步培养意识。

python建立类的代码如下:

class Province(object):

    #静态字段

    memo = '中国的23个省之一'

   

    def __init__(self,name,capital,leader,flag):

        self.Name = name

        self.Capital = capital

        self.Leader = leader

       

        #私有字段

        self.__Thailand = flag

       

    def sports_meet(self):

        print self.Name + '正在开运动会'

这里面,Province是一个类,__init__是类的构造方法,实例化一个对象,必须有构造方法,其中的self变量相似于java’this’,只是java是一个完全的面向对象语言,不需要赋有this这一变量,而python因为一些历史原因,综合了面向对象和函数式编程,一些语言的差别也来于此,理解这一点,才能明白与其他语言相关语法不同的缘由所在。类的非静态方法都需要self这一变量。

静态字段:静态字段是指直接在类体中定义,通过类.字段进行访问的;

静态方法:

@staticmethod

def Foo():

print '反腐'

即在方法上加上一个@staticmethod的装饰器,即代表是静态方法,这一语法也是与java等面向对象语言的折中选择,因为python不同于java等语言,在定义函数或者字段时,在之前就加上类型等信息,python是自动识别类型的,这是它的特点,而静态方法又必须在之前加上标识,所以就出现了这种装饰器来修饰的情况。

   特性的概念:

@property

    def Bar(self):

        return 'nothing'

定义一个类方法,加上property装饰器,则在类的方法调用的时候将不以方法的形式调用,而是以字段的形式调用

私有方法:

def __sha(self):

 print '逗比'

私有字段:

self.__Thailand = flag

即在前面加上__代表其为私有方法或者字段,不同于java等语言私有属性和方法不能被类外调用,python可以采取一种方法,使得可以访问类的私有属性或者方法。

@Thailand.setter

def Thailand(self,value):

    self.__Thailand = value

通过这个特性的方式,使得;类外可以访问,但是既然是静态的方法,理论上还是不要进行类外的访问,python这样的设计,其实还是属于历史的折中。

析构函数:回收赋给类对象的内存空间,当该对象执行完所有的方法,调用所有的属性之后,将会执行析构方法,具体如:

def __del__(self):

        print 'game over'

__call__()方法:一般类的方法的调用时是对象.方法(),而call方法直接是对象()就可以了。

继承:同其他面向对象式的语言一样,python继承的概念也是类似的。继承父类的方法,重写父类的方法。子类调用父类的方法,有两种方式,如调用父类的构造方法;

Father.__init__(self)

super(Son,self).__init__()

经典类和新式类的区别:以上创建类的时候,即使是父类,都是继承object

  1. 异常的处理

python的异常处理同其他语言(如JAVA类似),基本语法如下:

try:

except xxError,e:

except Exception,e:

else:

finally:finally后面语句无论异常执行与否,都将执行)

自定义异常:

class MyException(Exception):

   

    def __init__(self,msg):

        self.error = msg

    

    # print输出类的相关信息  

    def __str__(self,*args,**kwargs):

        return self.error

  

obj = MyException('错误')

print obj

这样就定义了一个自定义异常。

raise exception的作用:当我们写如下的操作时:

def Validate(name,pwd):

   

    if name == 'alex' and pwd == '123':

        return True

    else:

        return False

 

try:   

    res = Validate('alex', '456')

    if res:

        print 'success'

    else:

#         print 'Error'

# 节省代码

        raise Exception('Error')

except Exception,e:

    print e

print 'database'

打印错误时,可能之后还要进行其他的操作,如上述的打印信息,或者回归到某页面,多个错误可能会归于到一个页面,这样可能节省代码。

这一天主要介绍的是面向对象的思想,要注意与其他面向对象语言的异同。

posted @ 2016-04-29 14:30  focky  阅读(337)  评论(0编辑  收藏  举报