Python 学习笔记 ====== ### 类型 python 有四种类型,分别时整数,长整数,浮点数和复数 1. 整数,普通的使用方法,如2, 56,65535等等 2. 长整数,就是表示范围更大的整数 3. 浮点数,3.23, 3.4E-4表示的时3.4乘以10的-4次方 4. 复数,(-5+4j) ### 字符串 *自然字符串*:前面加上r或者R来表示的,如r"This is a test\n"。这样,就会照它原来的样子翻译,而不会使用转义字符翻译字符串了。(使用正则表达式的话需要使用自然字符串) *Unicode字符串*: 使用Unicode编码字符串(特别时对于不仅仅包含英文的字符串) 连接字符串:当两个字符串直接相邻时会自动连接起来。比如,'what\'s this ''is a bug',这两个字符串会被自动连接为'what\'s this is a bug' *转义符*: 单引号使用一个'\\'来转义,双引号使用两个`\\`来转义显示。行末加上`\`可以连接字符串,而不是换行。 *字符串是不可变的* *单引号和双引号是表达的意义是一样的* ### 引号 + 单引号:指示一个字符串 + 双引号:指示一个字符串(与单引号相同,里面可以包含单引号,直接输出而非转义) + 三引号:指示多个字符串,可以包括多行 > 单引号的例子: 'what is this', 'what\'s this' (里面使用了转义字符) > 双引号的例子 “what is this”, "what's this"(对于里面的单引号不需要使用转义字符,直接输出) > 三引号的例子 \'''This is the first line sencond line third line''' ### 基本的数据类型是数和字符串,后面的类型为类 ### 关于运行方式的一些说明: Python的运行方式,和其他程序脚本语言的方式是一样的,运行程序,脚本都是可执行的程序,因为是解释型语言。可以直接用python xxx.py的方式运行,指定了解释器就是python,也可以在脚本的头部加入 #!/usr/bin/python 的方式来指定解释运行的脚本,然后赋予可执行的权限,chmod +x xx.py,这样在Linux下面就可以使用./xx.py的方式来直接运行这个脚本。 ### Python的类型 对于C/C++语言的程序员而言,python是没有类型的,不需要声明类型,直接使用变量就可以了。另外,字符串是无法修改的,只能修改的是变量。 ### Python的物理行和逻辑行 + 物理行:就是*程序员*的眼光看到的一行。实际上就是物理上看到的一行一行的概念。 + 逻辑行:就是*Python*程序解释语言时认为的一行 一些例子说明物理行和逻辑行的关系: 1. i = 5; print i(一个物理行对应多个逻辑行) 从字面上可以看到只占用了一行,因此物理行就是一行,而这个语句包含一个分号,因此被python认为是两个语句(*强烈建议不要使用分号,大部分python程序中都没有分号,而且最好一个物理行对应一个逻辑行*) 2. s = ''' This is the first line \ This is the second line'''(一个逻辑行对应多个物理行) 这就是签名所说到的以\来连接字符串的,从物理行角度看有多行,而python则认为他们是一行,因此就有这种关系。(*明确的行连接*,不明确的使用圆括号,方括号等,后续继续学习) ### 缩进 Python中的缩进非常重要,同一个块中的缩进必须相同,否则*不能运行*。 保持良好的编程风格,使用统一的缩进,不要混合使用空格和制表符。 ## 运算符和表达式 大部分运算符和C/C++,Java中的类似,但是Python有几个特殊的需要注意一下: + 幂运算符(`**`),比如`3 ** 4` = 81 + 取整数运算符(`//`),比如 5 // 4 = 1(整数部分) + 逻辑运算符(and, or, not),这些运算符不同于&&, ||, !这些C/C++的运算符,注意一下。 ## 控制流笔记待补充 ## 控制流 *break*: 特别注意,如果从for或者while循环中终止的话,则对应的else从句永远都不会执行。(break终止的情况) *continue*:忽略后面执行语句,继续执行循环(与break不同,break会退出循环) ### 函数 可以给一个块定义一个函数,该函数能够在程序任何地方多次调用。 *函数的定义方法:* 使用def关键字,并且后面接上函数名称,然后括号,括号中可以使用变量名,最后接上冒号即可。注意一个函数就是一个块,所以要注意缩进。 函数可以给定参数,传递的参数位实参,而函数原型中定义的参数为形参。 ### 局部变量和全局变量 函数内定义的变量为局部变量,对于局部变量的修改仅限于函数内部,无法影响到外面。如果内部想使用外面的变量,使用global标识符来标记这个变量是外部定义的,这样,我们再对这个变量进行修改的时候,就是修改的外部变量,就可以在函数体内部修改外部变量,影响外面的值。 ### 默认参数值 使用等于号为默认参数指定值,这样用户可以不指定该参数,默认使用该参数,即原型中有两个参数,我可以只指定一个,第二个使用默认的参数(这样要原型定义了默认参数) *注意*:默认参数的默认值必须是定值,不可变的。另外,和C++一样,默认的参数值必须放在右边,不能先是默认参数,后是必须参数。 ### 关键参数 通过函数名来指定值,以前的C/C++等语言和python的前面哪些方式,都是通过位置,按照先后顺序依次赋值的,参数传递就只有这种方式。 而这里python可以通过指定变量名来指定参数,如果不是变量的,则使用位置变量,即按照定义的位置顺序来赋值操作。 ### 返回值 如果没有返回值的话,python默认返回None,即空 如果函数体不定义的话,相当于一个Pass语句(空语句) ### DocStrings 可以在类,模板,函数中增加文档字符串信息,以函数为例,在函数的第一行,用三引号描述该函数功能,然后空行,接下来一行再详细描述,并结束字符串。 最后,可以使用function.__doc__的方式来输出这些文档字符串信息 该信息可以用来自动生成说明文档,或者帮助文档等 ## 模块 使用import xxx来引用某个模块,如果要使用模块的成员,用点号运算符,如sys.argv表示的就是输入参数的列表信息,注意的是该列表的第一个参数是脚本的名称,后面才是列表内容。 可以使用模块中的变量信息,而且不必要担心名称重复,因为签名sys的模块名已经定义了模块。另外,关于模块放置的路径,在当前文件夹是可以的,否则就要放在system的path下面,否则是找不到的。 模块的文件名必须以py结束,模块的目的就是为了复用。(函数当然也是可以的,不过要实现更为庞大的复用则需要用到模块) ### pyc文件 二进制文件,起到隐藏源码的作用,而且与平台无关,需要注意的是,不同版本的python编译出来的pyc文件是不同的,不能通用。 如果要避免输入sys的话,可以使用from sys import argv,这样以后使用argv的话就是用的sys中,不过这个不是好的做法,因为可能有名称冲突,而且不易读(使用sys.argv更易读) ### 模块名称 模块名称使用__name__来标记,使用场景: 有些代码只想在主块中执行时才使用,而作为其他模块的子模块(输入,也就是说其他模块调用这个模块的时候)时不想执行,可以使用到该变量来标记: if __name__ == '__main__': xxxxx ### 作为主块的时候执行 else: yyyyy ### 只在子模块的时候执行 这样,比如为test.py文件,那么直接运行./test.py的时候,执行的为main,此时执行xxxxx,而如果是利用import test的方式,执行(命令行中,python, import test)的话,则作为子模块执行,此时执行的是yyyyy。 ### dir() dir不提供参数,则会列出当前模块定义的列表,如果给定参数,即模块名,则会列出该模块定义的名称列表。 可以使用del删除一个参数,就像从来没有存在过一样。 dir()会列出所有名称列表,而del会删除对应的名称列表,此时再用dir()会发现不再存在。 ## 数据结构 Python有三种数据结构,列表,元祖和字典 ### 列表 列表以方括号来表示,是一个类(就像int也是一个类一样,可以访问列表的函数,比如mylist.append函数就是向列表的末尾添加元素一样),每一个项目通过逗号分开 下面就是一个列表的例子: ['test', 'a', 'bbbb'] 需要注意的是,list是可变的,而字符串是不可变的,因此对list的修改,比如增加,删除,添加等,都会改变原有list的状态(具体关于list的函数可以参照help文档) ### 元祖(tuple) 元祖是*不可变*的,因此不能修改它的值。元祖使用的是圆括号和逗号分开, 元祖可以直接叠加,比如: zoo = ('monkey', 'tiger', 'snake') new_zoo = ('elephane', 'dolphine', zoo) 那么就可以直接用zoo构建一个新的对象new_zoo,而且可以通过下标访问元素,比如,zoo[2], new_zoo[0], new_zoo[2][2]等等,注意下标起始为0,而不是1. #### Tips #### 1. 列表之中的列表不会失去它的身份,即列表不会像Perl中那样被打散。同样元组中的元组,或列表中的元组,或元组中的列表等等都是如此。只要是Python,它们就只是使用另一个对象存储的对象。 2. 一个空的元组由一对空的圆括号组成,你必须在第一个(唯一一个)项目后跟一个逗号,这样Python才能区分元组和表达式中一个带圆括号的对象。即如果你想要的是一个包含项目2的元组的时候,你应该指明singleton = (2 , ) 3. 元组和打印语句(使用%s, %d来打印对应的输出结果) 如: 'Her name is %d, age is %d' %(name, age) ## 分别对应替换位对应的值 注意和C/C++不同的是,这里没有逗号分割开来,直接是字符串加上%来进行转换 ### 字典 表示方法:使用花括号包围,并用冒号表示一个个键值对,然后以逗号分割开来。 如:{key1:value1, key2:value2}, #### Tips 键是唯一的,不可变的,而且最好简单,值则可以是可变的或者不可变的。 ### 序列 列表,元组和字符串都是序列,序列支持的是index操作和slice操作,即index可以直接通过下标来访问元素,而slice则可以通过切片访问一部分元素。 python的下标从0开始,可以为负数,-1表示最后一个元素 *Note*:注意的是,切片的时候提供两个下标,比如[1:5]表示的从[1,5),即这个范围表示的从起始位置开始(含起始位置),不包括最后一个下标,即只能表示1,2,3,4这四个元素的索引。 ### 参考Reference 当对一个变量赋值,用对象传值的时候,注意变量自己不是一个新的对象,而只是只想原来的对象而已。 如: list = ['a', 'b', 'c'] mylist = list del list[0] print list print mylist ###注意的是list和mylist都是指向相同对象,因此都没有第一个元素 而如果似乎拷贝的话则不同,如 mylist = list[1:3],此时会创建新的对象 ### 字符串的内容str 关于具体的内容可以参考help文档中关于str的描述。 几个常见的用到哦啊的函数: startswith(): 以……开始 contains():包含…… find():查找是否有某个子字符串 ### 附:正确使用帮助 可以在命令行中进入python后,输入help('xxx')来查询关于xxx的文档,注意,一定要加上引号,否则会提示错误。 也可以输入help(),进入到help>模式,此时直接输入xxx,就可以查询到相关信息。 ### 解决问题(一个实际的小项目) 项目简介:做一个备份系统,能够将某些目录下面的文件备份到某个指定目录下面,并以zip包的形式打包,文件名为备份时候的时间。 知识点总结: 1. 需要使用到的库包括,time,os,其中time库用来获取备份时候的时间,使用 filename = time.strftime("%Y%m%d%H%M%S") + '.zip' 来保存获取算时间,特别注意的是这里括号中的字符大小写一定要弄清楚,否则会出现显示的时间不对(具体的format可能还需要再研究一下) 2. 执行某些系统命令,需要使用os库中的system方法实现,比如这里zip打包命令: os.system(command) 这里就是执行command = zip -qr dest src 的命令,只是说需要转换一下格式,比如字符串拼接,处理,格式化字符串而已。 3. 还需要一些字符串的处理,比如多个目录的连接,组合成为一个字符串,这样作为zip的第二个参数,即待压缩的路径,此时用的是: ' '.join(source) 来处理,表示对于元祖source中的每个项目都用空格来链接起来。 ### 软件开发流程 1. 什么(分析) 2. 如何(设计) 3. 编写(实施) 4. 测试(测试与调试) 5. 使用(实施或开发) 6. 维护(优化) 从上面这个小程序可以看到,Python的功能很强大,可以完成这些工作,而且代码量很小。特别是,从改进的V1到V4版本,每一个都是在原有的旧的 基础上完成的,因此可以看到,软件的开发,前期需要分析,从简单入手,完成某些特性后,使用,调试Bug,如果发现有新的feature,则加入需求 中,并继续开发,如果有问题,则调试。测试工作也非常重要,整个过程一气呵成 ## 面向对象与类 1 Python的类的函数都有一个默认的参数,不需要你赋值,该变量就是指这个类本省,通常命名为self。 2. 使用对象的类方法,直接和原来定义函数的方法类似,def定义函数即可,需要注意的是,要加上那个默认的参数self,即使函数体为空,然后再调用这个函数的时候,又不需要传递参数,同上面的说法(另外,新建一个类对象不是像C++那样new出来,直接调用类构造函数即可) 3. __init__方法 相当于C/C++中的构造函数的方法,并不需要显示调用,用来完成创建对象时候的初始化工作。 4. __dele__方法 相当于析构函数,只不过不能保证它是何时执行的。 5. 类变量和对象变量 类变量是该类的对象所共有的,相当于static变量,所有的对象对它的修改都会影响到它的值。对象变量则是对象独有的,每一个对象都有这样一份拷贝。 定义类变量就是在类中直接定义,而对象变量则是通过构造函数来传递参数的形式进行赋值和初始化 6. 继承。使用元组的方式来定义继承关系,如: class myclass(superclass): 这种方式来定义继承的关系,即myclass继承自superclass来实现。 注意:python不会自动调用基类的构造函数,需要自己手动指定调用。 另外,调用时还需要注意使用到self参数,保证参数的完整性